diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 662bcc5d61e75..f3b2a64df853b 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -1013,9 +1013,10 @@ # its historical default, but when compiling the compiler itself, we skip it by # default since we know it's safe to do so in that case. # -# On Windows platforms, packed debuginfo is the only supported option, -# producing a `.pdb` file. -#split-debuginfo = if linux { off } else if windows { packed } else if apple { unpacked } +# On Windows MSVC platforms, packed debuginfo is the only supported option, +# producing a `.pdb` file. On Windows GNU rustc doesn't support splitting debuginfo, +# and enabling it causes issues. +#split-debuginfo = if linux || windows-gnu { off } else if windows-msvc { packed } else if apple { unpacked } # Path to the `llvm-config` binary of the installation of a custom LLVM to link # against. Note that if this is specified we don't compile LLVM at all for this diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index eafa30b4e86cf..fa44a37125fd2 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1310,9 +1310,13 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { } GenericArg::Type(self.lower_ty_alloc(ty, itctx).try_as_ambig_ty().unwrap()) } - ast::GenericArg::Const(ct) => GenericArg::Const( - self.lower_anon_const_to_const_arg_and_alloc(ct).try_as_ambig_ct().unwrap(), - ), + ast::GenericArg::Const(ct) => { + let ct = self.lower_anon_const_to_const_arg_and_alloc(ct); + match ct.try_as_ambig_ct() { + Some(ct) => GenericArg::Const(ct), + None => GenericArg::Infer(hir::InferArg { hir_id: ct.hir_id, span: ct.span }), + } + } } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 4ba5dc541342a..be97d4f17dba8 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -737,6 +737,23 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere TokenTree::Token(token, spacing) => { let token_str = self.token_to_string_ext(token, convert_dollar_crate); self.word(token_str); + // Emit hygiene annotations for identity-bearing tokens, + // matching how print_ident() and print_lifetime() call ann_post(). + match token.kind { + token::Ident(name, _) => { + self.ann_post(Ident::new(name, token.span)); + } + token::NtIdent(ident, _) => { + self.ann_post(ident); + } + token::Lifetime(name, _) => { + self.ann_post(Ident::new(name, token.span)); + } + token::NtLifetime(ident, _) => { + self.ann_post(ident); + } + _ => {} + } if let token::DocComment(..) = token.kind { self.hardbreak() } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 9aa8f7a2067a5..47f14dc3df62e 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -374,10 +374,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.body } - fn unsized_feature_enabled(&self) -> bool { - self.tcx().features().unsized_fn_params() - } - /// Equate the inferred type and the annotated type for user type annotations #[instrument(skip(self), level = "debug")] fn check_user_type_annotations(&mut self) { @@ -660,7 +656,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } - if !self.unsized_feature_enabled() { + if !self.tcx().features().unsized_fn_params() { let trait_ref = ty::TraitRef::new( tcx, tcx.require_lang_item(LangItem::Sized, self.last_span), @@ -936,9 +932,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } - // When `unsized_fn_params` is enabled, only function calls - // and nullary ops are checked in `check_call_dest`. - if !self.unsized_feature_enabled() { + // When `unsized_fn_params` is enabled, this is checked in `check_call_dest`, + // and `hir_typeck` still forces all non-argument locals to be sized (i.e., we don't + // fully re-check what was already checked on HIR). + if !self.tcx().features().unsized_fn_params() { match self.body.local_kind(local) { LocalKind::ReturnPointer | LocalKind::Arg => { // return values of normal functions are required to be @@ -1953,8 +1950,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // When `unsized_fn_params` is not enabled, - // this check is done at `check_local`. - if self.unsized_feature_enabled() { + // this check is done at `visit_local_decl`. + if self.tcx().features().unsized_fn_params() { let span = term.source_info.span; self.ensure_place_sized(dest_ty, span); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index bf97bfb1ebbce..9396bf6352c59 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2874,6 +2874,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, ) -> Const<'tcx> { let tcx = self.tcx(); + + let ty = if !ty.has_infer() { Some(ty) } else { None }; + if let LitKind::Err(guar) = *kind { return ty::Const::new_error(tcx, guar); } @@ -2905,16 +2908,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; let lit_input = match expr.kind { - hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: lit.node, ty, neg: false }), + hir::ExprKind::Lit(lit) => { + Some(LitToConstInput { lit: lit.node, ty: Some(ty), neg: false }) + } hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind { - hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: lit.node, ty, neg: true }), + hir::ExprKind::Lit(lit) => { + Some(LitToConstInput { lit: lit.node, ty: Some(ty), neg: true }) + } _ => None, }, _ => None, }; lit_input.and_then(|l| { - if const_lit_matches_ty(tcx, &l.lit, l.ty, l.neg) { + if const_lit_matches_ty(tcx, &l.lit, ty, l.neg) { tcx.at(expr.span) .lit_to_const(l) .map(|value| ty::Const::new_value(tcx, value.valtree, value.ty)) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 9faa75e18480d..f53259e91eec1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -11,7 +11,7 @@ use rustc_hir::attrs::DivergingBlockBehavior; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; -use rustc_hir::{Expr, ExprKind, HirId, LangItem, Node, QPath, is_range_literal}; +use rustc_hir::{Expr, ExprKind, FnRetTy, HirId, LangItem, Node, QPath, is_range_literal}; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, PermitVariants}; use rustc_index::IndexVec; @@ -1587,6 +1587,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } err.span_note(spans, format!("{} defined here", self.tcx.def_descr(def_id))); + if let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(def_id) + && let ty::Param(_) = + self.tcx.fn_sig(def_id).instantiate_identity().skip_binder().output().kind() + && let parent = self.tcx.hir_get_parent_item(call_expr.hir_id).def_id + && let Some((output, body_id)) = match self.tcx.hir_node_by_def_id(parent) { + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn { sig, body, .. }, + .. + }) + | hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body)), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Fn(sig, body), + .. + }) => Some((sig.decl.output, body)), + _ => None, + } + && let expr = self.tcx.hir_body(*body_id).value + && (expr.peel_blocks().span == call_expr.span + || matches!( + self.tcx.parent_hir_node(call_expr.hir_id), + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. }) + )) + { + err.span_label( + output.span(), + match output { + FnRetTy::DefaultReturn(_) => format!( + "this implicit `()` return type influences the call expression's return type" + ), + FnRetTy::Return(_) => { + "this return type influences the call expression's return type" + .to_string() + } + }, + ); + } } else if let Some(hir::Node::Expr(e)) = self.tcx.hir_get_if_local(def_id) && let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind { diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index fe95a682c6376..a7c5943c250b8 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -49,6 +49,11 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { let Some((pat, arg)) = extract_for_loop(expr) else { return }; + // Do not put suggestions for external macros. + if pat.span.from_expansion() { + return; + } + let arg_span = arg.span.source_callsite(); let ty = cx.typeck_results().expr_ty(arg); @@ -77,6 +82,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { }; let sub = if let Some(recv) = extract_iterator_next_call(cx, arg) + && recv.span.can_be_used_for_suggestions() + && recv.span.between(arg_span.shrink_to_hi()).can_be_used_for_suggestions() && let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span) { ForLoopsOverFalliblesLoopSub::RemoveNext { diff --git a/compiler/rustc_middle/src/ty/consts/lit.rs b/compiler/rustc_middle/src/ty/consts/lit.rs index be6dfb20e0433..7be225a9e9215 100644 --- a/compiler/rustc_middle/src/ty/consts/lit.rs +++ b/compiler/rustc_middle/src/ty/consts/lit.rs @@ -10,7 +10,10 @@ pub struct LitToConstInput<'tcx> { /// The absolute value of the resultant constant. pub lit: LitKind, /// The type of the constant. - pub ty: Ty<'tcx>, + /// + /// `None` is used by const generics when the type of the constant is unknown, e.g. + /// if there are inference variables + pub ty: Option>, /// If the constant is negative. pub neg: bool, } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index ad6c1f7dce5b8..c67d99a8eb7de 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -50,7 +50,8 @@ pub(crate) fn as_constant_inner<'tcx>( match *kind { ExprKind::Literal { lit, neg } => { - let const_ = lit_to_mir_constant(tcx, LitToConstInput { lit: lit.node, ty, neg }); + let const_ = + lit_to_mir_constant(tcx, LitToConstInput { lit: lit.node, ty: Some(ty), neg }); ConstOperand { span, user_ty: None, const_ } } @@ -109,6 +110,8 @@ pub(crate) fn as_constant_inner<'tcx>( fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>) -> Const<'tcx> { let LitToConstInput { lit, ty, neg } = lit_input; + let ty = ty.expect("type of literal must be known at this point"); + if let Err(guar) = ty.error_reported() { return Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar)); } diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index b4eedb15033c8..019af24613541 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -31,25 +31,27 @@ pub(crate) fn lit_to_const<'tcx>( .unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result)) }; - let (valtree, valtree_ty) = match (lit, expected_ty.kind()) { + let (valtree, valtree_ty) = match (lit, expected_ty.map(|ty| ty.kind())) { (ast::LitKind::Str(s, _), _) => { let str_bytes = s.as_str().as_bytes(); let valtree_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, tcx.types.str_); (ty::ValTree::from_raw_bytes(tcx, str_bytes), valtree_ty) } - (ast::LitKind::ByteStr(byte_sym, _), ty::Ref(_, inner_ty, _)) + (ast::LitKind::ByteStr(byte_sym, _), Some(ty::Ref(_, inner_ty, _))) if let ty::Slice(ty) | ty::Array(ty, _) = inner_ty.kind() && let ty::Uint(UintTy::U8) = ty.kind() => { - (ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()), expected_ty) + (ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()), expected_ty.unwrap()) } - (ast::LitKind::ByteStr(byte_sym, _), ty::Slice(inner_ty) | ty::Array(inner_ty, _)) - if tcx.features().deref_patterns() - && let ty::Uint(UintTy::U8) = inner_ty.kind() => + ( + ast::LitKind::ByteStr(byte_sym, _), + Some(ty::Slice(inner_ty) | ty::Array(inner_ty, _)), + ) if tcx.features().deref_patterns() + && let ty::Uint(UintTy::U8) = inner_ty.kind() => { // Byte string literal patterns may have type `[u8]` or `[u8; N]` if `deref_patterns` is // enabled, in order to allow, e.g., `deref!(b"..."): Vec`. - (ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()), expected_ty) + (ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()), expected_ty.unwrap()) } (ast::LitKind::ByteStr(byte_sym, _), _) => { let valtree = ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()); @@ -79,11 +81,11 @@ pub(crate) fn lit_to_const<'tcx>( trunc(if neg { u128::wrapping_neg(n.get()) } else { n.get() }, i.to_unsigned()); (ty::ValTree::from_scalar_int(tcx, scalar_int), Ty::new_int(tcx, i)) } - (ast::LitKind::Int(n, ast::LitIntType::Unsuffixed), ty::Uint(ui)) if !neg => { + (ast::LitKind::Int(n, ast::LitIntType::Unsuffixed), Some(ty::Uint(ui))) if !neg => { let scalar_int = trunc(n.get(), *ui); (ty::ValTree::from_scalar_int(tcx, scalar_int), Ty::new_uint(tcx, *ui)) } - (ast::LitKind::Int(n, ast::LitIntType::Unsuffixed), ty::Int(i)) => { + (ast::LitKind::Int(n, ast::LitIntType::Unsuffixed), Some(ty::Int(i))) => { // Unsigned "negation" has the same bitwise effect as signed negation, // which gets the result we want without additional casts. let scalar_int = @@ -101,7 +103,7 @@ pub(crate) fn lit_to_const<'tcx>( let bits = parse_float_into_scalar(n, fty, neg)?; (ty::ValTree::from_scalar_int(tcx, bits), Ty::new_float(tcx, fty)) } - (ast::LitKind::Float(n, ast::LitFloatType::Unsuffixed), ty::Float(fty)) => { + (ast::LitKind::Float(n, ast::LitFloatType::Unsuffixed), Some(ty::Float(fty))) => { let bits = parse_float_into_scalar(n, *fty, neg)?; (ty::ValTree::from_scalar_int(tcx, bits), Ty::new_float(tcx, *fty)) } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 67cde0e2c8866..fec2fb9ca5719 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -696,7 +696,7 @@ impl<'tcx> PatCtxt<'tcx> { // patterns to `str`, and byte-string literal patterns to `[u8; N]` or `[u8]`. let pat_ty = self.typeck_results.node_type(pat.hir_id); - let lit_input = LitToConstInput { lit: lit.node, ty: pat_ty, neg: *negated }; + let lit_input = LitToConstInput { lit: lit.node, ty: Some(pat_ty), neg: *negated }; let constant = const_lit_matches_ty(self.tcx, &lit.node, pat_ty, *negated) .then(|| self.tcx.at(expr.span).lit_to_const(lit_input)) .flatten() diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 5cb8922574b61..7fcaea3a629f1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -158,6 +158,7 @@ impl UnderspecifiedArgKind { struct ClosureEraser<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, + depth: usize, } impl<'a, 'tcx> ClosureEraser<'a, 'tcx> { @@ -172,7 +173,8 @@ impl<'a, 'tcx> TypeFolder> for ClosureEraser<'a, 'tcx> { } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - match ty.kind() { + self.depth += 1; + let ty = match ty.kind() { ty::Closure(_, args) => { // For a closure type, we turn it into a function pointer so that it gets rendered // as `fn(args) -> Ret`. @@ -233,9 +235,15 @@ impl<'a, 'tcx> TypeFolder> for ClosureEraser<'a, 'tcx> { // its type parameters. ty.super_fold_with(self) } - // We don't have an unknown type parameter anywhere, replace with `_`. + // We are in the top-level type, not one of its type parameters. Name it with its + // parameters replaced. + _ if self.depth == 1 => ty.super_fold_with(self), + // We don't have an unknown type parameter anywhere, and we are in a type parameter. + // Replace with `_`. _ => self.new_infer(), - } + }; + self.depth -= 1; + ty } fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> { @@ -287,7 +295,7 @@ fn ty_to_string<'tcx>( let ty = infcx.resolve_vars_if_possible(ty); // We use `fn` ptr syntax for closures, but this only works when the closure does not capture // anything. We also remove all type parameters that are fully known to the type system. - let ty = ty.fold_with(&mut ClosureEraser { infcx }); + let ty = ty.fold_with(&mut ClosureEraser { infcx, depth: 0 }); match (ty.kind(), called_method_def_id) { // We don't want the regular output for `fn`s because it includes its path in @@ -467,6 +475,25 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { term: Term<'tcx>, error_code: TypeAnnotationNeeded, should_label_span: bool, + ) -> Diag<'a> { + self.emit_inference_failure_err_with_type_hint( + body_def_id, + failure_span, + term, + error_code, + should_label_span, + None, + ) + } + + pub fn emit_inference_failure_err_with_type_hint( + &self, + body_def_id: LocalDefId, + failure_span: Span, + term: Term<'tcx>, + error_code: TypeAnnotationNeeded, + should_label_span: bool, + ty: Option>, ) -> Diag<'a> { let term = self.resolve_vars_if_possible(term); let arg_data = self @@ -479,7 +506,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return self.bad_inference_failure_err(failure_span, arg_data, error_code); }; - let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, term); + let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, term, ty); if let Some(body) = self.tcx.hir_maybe_body_owned_by( self.tcx.typeck_root_def_id(body_def_id.to_def_id()).expect_local(), ) { @@ -779,10 +806,20 @@ impl<'tcx> InferSourceKind<'tcx> { | InferSourceKind::ClosureReturn { ty, .. } => { if ty.is_closure() { ("closure", closure_as_fn_str(infcx, ty), long_ty_path) - } else if !ty.is_ty_or_numeric_infer() { - ("normal", infcx.tcx.short_string(ty, &mut long_ty_path), long_ty_path) - } else { + } else if ty.is_ty_or_numeric_infer() + || ty.is_primitive() + || matches!( + ty.kind(), + ty::Adt(_, args) + if args.types().count() == 0 && args.consts().count() == 0 + ) + { + // `ty` is either `_`, a primitive type like `u32` or a type with no type or + // const parameters. We will not mention the type in the main inference error + // message. ("other", String::new(), long_ty_path) + } else { + ("normal", infcx.tcx.short_string(ty, &mut long_ty_path), long_ty_path) } } // FIXME: We should be able to add some additional info here. @@ -815,6 +852,7 @@ struct FindInferSourceVisitor<'a, 'tcx> { typeck_results: &'a TypeckResults<'tcx>, target: Term<'tcx>, + ty: Option>, attempt: usize, infer_source_cost: usize, @@ -826,12 +864,14 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { tecx: &'a TypeErrCtxt<'a, 'tcx>, typeck_results: &'a TypeckResults<'tcx>, target: Term<'tcx>, + ty: Option>, ) -> Self { FindInferSourceVisitor { tecx, typeck_results, target, + ty, attempt: 0, infer_source_cost: usize::MAX, @@ -1213,7 +1253,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { fn visit_local(&mut self, local: &'tcx LetStmt<'tcx>) { intravisit::walk_local(self, local); - if let Some(ty) = self.opt_node_type(local.hir_id) { + if let Some(mut ty) = self.opt_node_type(local.hir_id) { if self.generic_arg_contains_target(ty.into()) { fn get_did( typeck_results: &TypeckResults<'_>, @@ -1241,7 +1281,11 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { _ => None, } } - + if let Some(t) = self.ty + && ty.has_infer() + { + ty = t; + } if let LocalSource::Normal = local.source && local.ty.is_none() { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 7de8891196d85..7f5ed9ecb6d11 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -246,12 +246,37 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .find(|s| s.has_non_region_infer()); let mut err = if let Some(term) = term { - self.emit_inference_failure_err( + let candidates: Vec<_> = self + .tcx + .all_impls(trait_pred.def_id()) + .filter_map(|def_id| { + let imp = self.tcx.impl_trait_header(def_id); + if imp.polarity != ty::ImplPolarity::Positive + || !self.tcx.is_user_visible_dep(def_id.krate) + { + return None; + } + let imp = imp.trait_ref.skip_binder(); + if imp + .with_replaced_self_ty(self.tcx, trait_pred.skip_binder().self_ty()) + == trait_pred.skip_binder().trait_ref + { + Some(imp.self_ty()) + } else { + None + } + }) + .collect(); + self.emit_inference_failure_err_with_type_hint( obligation.cause.body_id, span, term, TypeAnnotationNeeded::E0283, true, + match &candidates[..] { + [candidate] => Some(*candidate), + _ => None, + }, ) } else { struct_span_code_err!( diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index d5383fd4d0831..6bf08170bcf7e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2251,6 +2251,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if candidates.is_empty() { return false; } + let mut specific_candidates = candidates.clone(); + specific_candidates.retain(|(tr, _)| { + tr.with_replaced_self_ty(self.tcx, trait_pred.skip_binder().self_ty()) + == trait_pred.skip_binder().trait_ref + }); + if !specific_candidates.is_empty() { + // We have found a subset of impls that fully satisfy the expected trait, only + // mention those types. + candidates = specific_candidates; + } if let &[(cand, def_id)] = &candidates[..] { if self.tcx.is_diagnostic_item(sym::FromResidual, cand.def_id) && !self.tcx.features().enabled(sym::try_trait_v2) diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 1d444079f8968..49e0bdde37870 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -58,7 +58,8 @@ fn recurse_build<'tcx>( } &ExprKind::Literal { lit, neg } => { let sp = node.span; - match tcx.at(sp).lit_to_const(LitToConstInput { lit: lit.node, ty: node.ty, neg }) { + match tcx.at(sp).lit_to_const(LitToConstInput { lit: lit.node, ty: Some(node.ty), neg }) + { Some(value) => ty::Const::new_value(tcx, value.valtree, value.ty), None => ty::Const::new_misc_error(tcx), } diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index aa1901314e37c..bc668f78bf740 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -87,6 +87,7 @@ use crate::sync::Arc; /// ``` #[cfg(target_has_atomic = "ptr")] #[stable(feature = "wake_trait", since = "1.51.0")] +#[rustc_diagnostic_item = "Wake"] pub trait Wake { /// Wake this task. #[stable(feature = "wake_trait", since = "1.51.0")] diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index b3dc435dda176..49d7487c2803b 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -357,6 +357,7 @@ pub const trait Eq: [const] PartialEq + PointeeSized { } /// Derive macro generating an impl of the trait [`Eq`]. +/// The behavior of this macro is described in detail [here](Eq#derivable). #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, derive_eq_internals, structural_match)] diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index d3d6495e75a2a..dfa27e32bc722 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -823,7 +823,7 @@ fn enc_16lsd(buf: &mut [MaybeUninit], n: u64) { let mut remain = n; // Format per four digits from the lookup table. - for quad_index in (0..4).rev() { + for quad_index in (1..4).rev() { // pull two pairs let quad = remain % 1_00_00; remain /= 1_00_00; @@ -834,6 +834,14 @@ fn enc_16lsd(buf: &mut [MaybeUninit], n: u64) { buf[quad_index * 4 + OFFSET + 2].write(DECIMAL_PAIRS[pair2 * 2 + 0]); buf[quad_index * 4 + OFFSET + 3].write(DECIMAL_PAIRS[pair2 * 2 + 1]); } + + // final two pairs + let pair1 = (remain / 100) as usize; + let pair2 = (remain % 100) as usize; + buf[OFFSET + 0].write(DECIMAL_PAIRS[pair1 * 2 + 0]); + buf[OFFSET + 1].write(DECIMAL_PAIRS[pair1 * 2 + 1]); + buf[OFFSET + 2].write(DECIMAL_PAIRS[pair2 * 2 + 0]); + buf[OFFSET + 3].write(DECIMAL_PAIRS[pair2 * 2 + 1]); } /// Euclidean division plus remainder with constant 1E16 basically consumes 16 diff --git a/library/core/src/num/imp/dec2flt/decimal.rs b/library/core/src/num/imp/dec2flt/decimal.rs index 27a53d4b9e75b..c9b0cc531b386 100644 --- a/library/core/src/num/imp/dec2flt/decimal.rs +++ b/library/core/src/num/imp/dec2flt/decimal.rs @@ -1,6 +1,6 @@ //! Representation of a float as the significant digits and exponent. -use dec2flt::float::RawFloat; +use dec2flt::Lemire; use dec2flt::fpu::set_precision; use crate::num::imp::dec2flt; @@ -36,7 +36,7 @@ pub struct Decimal { impl Decimal { /// Detect if the float can be accurately reconstructed from native floats. #[inline] - fn can_use_fast_path(&self) -> bool { + fn can_use_fast_path(&self) -> bool { F::MIN_EXPONENT_FAST_PATH <= self.exponent && self.exponent <= F::MAX_EXPONENT_DISGUISED_FAST_PATH && self.mantissa <= F::MAX_MANTISSA_FAST_PATH @@ -53,7 +53,7 @@ impl Decimal { /// /// There is an exception: disguised fast-path cases, where we can shift /// powers-of-10 from the exponent to the significant digits. - pub fn try_fast_path(&self) -> Option { + pub fn try_fast_path(&self) -> Option { // Here we need to work around . // The fast path crucially depends on arithmetic being rounded to the correct number of bits // without any intermediate rounding. On x86 (without SSE or SSE2) this requires the precision diff --git a/library/core/src/num/imp/dec2flt/lemire.rs b/library/core/src/num/imp/dec2flt/lemire.rs index c3f2723509d05..f89d16c843477 100644 --- a/library/core/src/num/imp/dec2flt/lemire.rs +++ b/library/core/src/num/imp/dec2flt/lemire.rs @@ -1,10 +1,9 @@ //! Implementation of the Eisel-Lemire algorithm. use dec2flt::common::BiasedFp; -use dec2flt::float::RawFloat; use dec2flt::table::{LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE}; -use crate::num::imp::dec2flt; +use crate::num::imp::{Float, dec2flt}; /// Compute w * 10^q using an extended-precision float representation. /// @@ -24,7 +23,7 @@ use crate::num::imp::dec2flt; /// at a Gigabyte per Second" in section 5, "Fast Algorithm", and /// section 6, "Exact Numbers And Ties", available online: /// . -pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { +pub fn compute_float(q: i64, mut w: u64) -> BiasedFp { let fp_zero = BiasedFp::zero_pow2(0); let fp_inf = BiasedFp::zero_pow2(F::INFINITE_POWER); let fp_error = BiasedFp::zero_pow2(-1); diff --git a/library/core/src/num/imp/dec2flt/mod.rs b/library/core/src/num/imp/dec2flt/mod.rs index 3f5724add62bb..76b8d416ee0f1 100644 --- a/library/core/src/num/imp/dec2flt/mod.rs +++ b/library/core/src/num/imp/dec2flt/mod.rs @@ -88,24 +88,104 @@ )] use common::BiasedFp; -use float::RawFloat; use lemire::compute_float; use parse::{parse_inf_nan, parse_number}; use slow::parse_long_mantissa; +use crate::f64; use crate::num::ParseFloatError; use crate::num::float_parse::FloatErrorKind; +use crate::num::imp::FloatExt; mod common; pub mod decimal; pub mod decimal_seq; mod fpu; -mod slow; -mod table; -// float is used in flt2dec, and all are used in unit tests. -pub mod float; pub mod lemire; pub mod parse; +mod slow; +mod table; + +/// Extension to `Float` that are necessary for parsing using the Lemire method. +/// +/// See the parent module's doc comment for why this is necessary. +/// +/// Not intended for use outside of the `dec2flt` module. +#[doc(hidden)] +pub trait Lemire: FloatExt { + /// Maximum exponent for a fast path case, or `⌊(SIG_BITS+1)/log2(5)⌋` + // assuming FLT_EVAL_METHOD = 0 + const MAX_EXPONENT_FAST_PATH: i64 = { + let log2_5 = f64::consts::LOG2_10 - 1.0; + (Self::SIG_TOTAL_BITS as f64 / log2_5) as i64 + }; + + /// Minimum exponent for a fast path case, or `-⌊(SIG_BITS+1)/log2(5)⌋` + const MIN_EXPONENT_FAST_PATH: i64 = -Self::MAX_EXPONENT_FAST_PATH; + + /// Maximum exponent that can be represented for a disguised-fast path case. + /// This is `MAX_EXPONENT_FAST_PATH + ⌊(SIG_BITS+1)/log2(10)⌋` + const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = + Self::MAX_EXPONENT_FAST_PATH + (Self::SIG_TOTAL_BITS as f64 / f64::consts::LOG2_10) as i64; + + /// Maximum mantissa for the fast-path (`1 << 53` for f64). + const MAX_MANTISSA_FAST_PATH: u64 = 1 << Self::SIG_TOTAL_BITS; + + /// Gets a small power-of-ten for fast-path multiplication. + fn pow10_fast_path(exponent: usize) -> Self; + + /// Converts integer into float through an as cast. + /// This is only called in the fast-path algorithm, and therefore + /// will not lose precision, since the value will always have + /// only if the value is <= Self::MAX_MANTISSA_FAST_PATH. + fn from_u64(v: u64) -> Self; +} + +#[cfg(target_has_reliable_f16)] +impl Lemire for f16 { + fn pow10_fast_path(exponent: usize) -> Self { + #[allow(clippy::use_self)] + const TABLE: [f16; 8] = [1e0, 1e1, 1e2, 1e3, 1e4, 0.0, 0.0, 0.]; + TABLE[exponent & 7] + } + + #[inline] + fn from_u64(v: u64) -> Self { + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); + v as _ + } +} + +impl Lemire for f32 { + fn pow10_fast_path(exponent: usize) -> Self { + #[allow(clippy::use_self)] + const TABLE: [f32; 16] = + [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 0., 0., 0., 0., 0.]; + TABLE[exponent & 15] + } + + #[inline] + fn from_u64(v: u64) -> Self { + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); + v as _ + } +} + +impl Lemire for f64 { + fn pow10_fast_path(exponent: usize) -> Self { + const TABLE: [f64; 32] = [ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, + 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 0., 0., 0., 0., 0., 0., 0., 0., 0., + ]; + TABLE[exponent & 31] + } + + #[inline] + fn from_u64(v: u64) -> Self { + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); + v as _ + } +} #[inline] pub(super) fn pfe_empty() -> ParseFloatError { @@ -120,7 +200,7 @@ pub fn pfe_invalid() -> ParseFloatError { } /// Converts a `BiasedFp` to the closest machine float type. -fn biased_fp_to_float(x: BiasedFp) -> F { +fn biased_fp_to_float(x: BiasedFp) -> F { let mut word = x.m; word |= (x.p_biased as u64) << F::SIG_BITS; F::from_u64_bits(word) @@ -128,7 +208,7 @@ fn biased_fp_to_float(x: BiasedFp) -> F { /// Converts a decimal string into a floating point number. #[inline(always)] // Will be inlined into a function with `#[inline(never)]`, see above -pub fn dec2flt(s: &str) -> Result { +pub fn dec2flt(s: &str) -> Result { let mut s = s.as_bytes(); let Some(&c) = s.first() else { return Err(pfe_empty()) }; let negative = c == b'-'; diff --git a/library/core/src/num/imp/dec2flt/parse.rs b/library/core/src/num/imp/dec2flt/parse.rs index e4049bc164c61..ee55eadbc7b9e 100644 --- a/library/core/src/num/imp/dec2flt/parse.rs +++ b/library/core/src/num/imp/dec2flt/parse.rs @@ -2,9 +2,8 @@ use dec2flt::common::{ByteSlice, is_8digits}; use dec2flt::decimal::Decimal; -use dec2flt::float::RawFloat; -use crate::num::imp::dec2flt; +use crate::num::imp::{Float, dec2flt}; const MIN_19DIGIT_INT: u64 = 100_0000_0000_0000_0000; @@ -197,7 +196,7 @@ pub fn parse_number(s: &[u8]) -> Option { } /// Try to parse a special, non-finite float. -pub(crate) fn parse_inf_nan(s: &[u8], negative: bool) -> Option { +pub(crate) fn parse_inf_nan(s: &[u8], negative: bool) -> Option { // Since a valid string has at most the length 8, we can load // all relevant characters into a u64 and work from there. // This also generates much better code. diff --git a/library/core/src/num/imp/dec2flt/slow.rs b/library/core/src/num/imp/dec2flt/slow.rs index 089b12f5be22e..f1b2525cf38e6 100644 --- a/library/core/src/num/imp/dec2flt/slow.rs +++ b/library/core/src/num/imp/dec2flt/slow.rs @@ -2,9 +2,8 @@ use dec2flt::common::BiasedFp; use dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq}; -use dec2flt::float::RawFloat; -use crate::num::imp::dec2flt; +use crate::num::imp::{Float, dec2flt}; /// Parse the significant digits and biased, binary exponent of a float. /// @@ -25,7 +24,7 @@ use crate::num::imp::dec2flt; /// /// The algorithms described here are based on "Processing Long Numbers Quickly", /// available here: . -pub(crate) fn parse_long_mantissa(s: &[u8]) -> BiasedFp { +pub(crate) fn parse_long_mantissa(s: &[u8]) -> BiasedFp { const MAX_SHIFT: usize = 60; const NUM_POWERS: usize = 19; const POWERS: [u8; 19] = diff --git a/library/core/src/num/imp/flt2dec/decoder.rs b/library/core/src/num/imp/flt2dec/decoder.rs index 3d6ad6608efe3..5ccc91f4c9faf 100644 --- a/library/core/src/num/imp/flt2dec/decoder.rs +++ b/library/core/src/num/imp/flt2dec/decoder.rs @@ -1,7 +1,7 @@ //! Decodes a floating-point value into individual parts and error ranges. use crate::num::FpCategory; -use crate::num::imp::dec2flt::float::RawFloat; +use crate::num::imp::FloatExt; /// Decoded unsigned finite value, such that: /// @@ -40,7 +40,7 @@ pub enum FullDecoded { } /// A floating point type which can be `decode`d. -pub trait DecodableFloat: RawFloat + Copy { +pub trait DecodableFloat: FloatExt + Copy { /// The minimum positive normalized value. fn min_pos_norm_value() -> Self; } diff --git a/library/core/src/num/imp/mod.rs b/library/core/src/num/imp/mod.rs index d35409f91bde9..6fccfd1c238ed 100644 --- a/library/core/src/num/imp/mod.rs +++ b/library/core/src/num/imp/mod.rs @@ -16,3 +16,6 @@ pub(crate) mod int_log10; pub(crate) mod int_sqrt; pub(crate) mod libm; pub(crate) mod overflow_panic; +mod traits; + +pub use traits::{Float, FloatExt, Int}; diff --git a/library/core/src/num/imp/dec2flt/float.rs b/library/core/src/num/imp/traits.rs similarity index 72% rename from library/core/src/num/imp/dec2flt/float.rs rename to library/core/src/num/imp/traits.rs index 21aabdc8addb4..7b84f7a4a5aa2 100644 --- a/library/core/src/num/imp/dec2flt/float.rs +++ b/library/core/src/num/imp/traits.rs @@ -1,10 +1,14 @@ -//! Helper trait for generic float types. +//! Numeric traits used for internal implementations. -use core::f64; +#![doc(hidden)] +#![unstable( + feature = "num_internals", + reason = "internal routines only exposed for testing", + issue = "none" +)] -use crate::fmt::{Debug, LowerExp}; use crate::num::FpCategory; -use crate::ops::{self, Add, Div, Mul, Neg}; +use crate::{f64, fmt, ops}; /// Lossy `as` casting between two types. pub trait CastInto: Copy { @@ -12,11 +16,11 @@ pub trait CastInto: Copy { } /// Collection of traits that allow us to be generic over integer size. -pub trait Integer: +pub trait Int: Sized + Clone + Copy - + Debug + + fmt::Debug + ops::Shr + ops::Shl + ops::BitAnd @@ -37,7 +41,7 @@ macro_rules! int { } } - impl Integer for $ty { + impl Int for $ty { const ZERO: Self = 0; const ONE: Self = 1; } @@ -48,27 +52,22 @@ macro_rules! int { int!(u16, u32, u64); /// A helper trait to avoid duplicating basically all the conversion code for IEEE floats. -/// -/// See the parent module's doc comment for why this is necessary. -/// -/// Should **never ever** be implemented for other types or be used outside the `dec2flt` module. #[doc(hidden)] -pub trait RawFloat: +pub trait Float: Sized - + Div - + Neg - + Mul - + Add - + LowerExp + + ops::Div + + ops::Neg + + ops::Mul + + ops::Add + + fmt::Debug + PartialEq + PartialOrd + Default + Clone + Copy - + Debug { /// The unsigned integer with the same size as the float - type Int: Integer + Into; + type Int: Int + Into; /* general constants */ @@ -128,8 +127,6 @@ pub trait RawFloat: const MIN_EXPONENT_ROUND_TO_EVEN: i32; const MAX_EXPONENT_ROUND_TO_EVEN: i32; - /* limits related to Fast pathing */ - /// Largest decimal exponent for a non-infinite value. /// /// This is the max exponent in binary converted to the max exponent in decimal. Allows fast @@ -151,41 +148,19 @@ pub trait RawFloat: /// compile time since intermediates exceed the range of an `f64`. const SMALLEST_POWER_OF_TEN: i32; - /// Maximum exponent for a fast path case, or `⌊(SIG_BITS+1)/log2(5)⌋` - // assuming FLT_EVAL_METHOD = 0 - const MAX_EXPONENT_FAST_PATH: i64 = { - let log2_5 = f64::consts::LOG2_10 - 1.0; - (Self::SIG_TOTAL_BITS as f64 / log2_5) as i64 - }; - - /// Minimum exponent for a fast path case, or `-⌊(SIG_BITS+1)/log2(5)⌋` - const MIN_EXPONENT_FAST_PATH: i64 = -Self::MAX_EXPONENT_FAST_PATH; - - /// Maximum exponent that can be represented for a disguised-fast path case. - /// This is `MAX_EXPONENT_FAST_PATH + ⌊(SIG_BITS+1)/log2(10)⌋` - const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = - Self::MAX_EXPONENT_FAST_PATH + (Self::SIG_TOTAL_BITS as f64 / f64::consts::LOG2_10) as i64; - - /// Maximum mantissa for the fast-path (`1 << 53` for f64). - const MAX_MANTISSA_FAST_PATH: u64 = 1 << Self::SIG_TOTAL_BITS; - - /// Converts integer into float through an as cast. - /// This is only called in the fast-path algorithm, and therefore - /// will not lose precision, since the value will always have - /// only if the value is <= Self::MAX_MANTISSA_FAST_PATH. - fn from_u64(v: u64) -> Self; - - /// Performs a raw transmutation from an integer. - fn from_u64_bits(v: u64) -> Self; - - /// Gets a small power-of-ten for fast-path multiplication. - fn pow10_fast_path(exponent: usize) -> Self; - /// Returns the category that this number falls into. fn classify(self) -> FpCategory; /// Transmute to the integer representation fn to_bits(self) -> Self::Int; +} + +/// Items that ideally would be on `Float`, but don't apply to all float types because they +/// rely on the mantissa fitting into a `u64` (which isn't true for `f128`). +#[doc(hidden)] +pub trait FloatExt: Float { + /// Performs a raw transmutation from an integer. + fn from_u64_bits(v: u64) -> Self; /// Returns the mantissa, exponent and sign as integers. /// @@ -219,7 +194,7 @@ const fn pow2_to_pow10(a: i64) -> i64 { } #[cfg(target_has_reliable_f16)] -impl RawFloat for f16 { +impl Float for f16 { type Int = u16; const INFINITY: Self = Self::INFINITY; @@ -236,23 +211,6 @@ impl RawFloat for f16 { const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 5; const SMALLEST_POWER_OF_TEN: i32 = -27; - #[inline] - fn from_u64(v: u64) -> Self { - debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); - v as _ - } - - #[inline] - fn from_u64_bits(v: u64) -> Self { - Self::from_bits((v & 0xFFFF) as u16) - } - - fn pow10_fast_path(exponent: usize) -> Self { - #[allow(clippy::use_self)] - const TABLE: [f16; 8] = [1e0, 1e1, 1e2, 1e3, 1e4, 0.0, 0.0, 0.]; - TABLE[exponent & 7] - } - fn to_bits(self) -> Self::Int { self.to_bits() } @@ -262,7 +220,15 @@ impl RawFloat for f16 { } } -impl RawFloat for f32 { +#[cfg(target_has_reliable_f16)] +impl FloatExt for f16 { + #[inline] + fn from_u64_bits(v: u64) -> Self { + Self::from_bits((v & 0xFFFF) as u16) + } +} + +impl Float for f32 { type Int = u32; const INFINITY: Self = f32::INFINITY; @@ -279,24 +245,6 @@ impl RawFloat for f32 { const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10; const SMALLEST_POWER_OF_TEN: i32 = -65; - #[inline] - fn from_u64(v: u64) -> Self { - debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); - v as _ - } - - #[inline] - fn from_u64_bits(v: u64) -> Self { - f32::from_bits((v & 0xFFFFFFFF) as u32) - } - - fn pow10_fast_path(exponent: usize) -> Self { - #[allow(clippy::use_self)] - const TABLE: [f32; 16] = - [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 0., 0., 0., 0., 0.]; - TABLE[exponent & 15] - } - fn to_bits(self) -> Self::Int { self.to_bits() } @@ -306,7 +254,14 @@ impl RawFloat for f32 { } } -impl RawFloat for f64 { +impl FloatExt for f32 { + #[inline] + fn from_u64_bits(v: u64) -> Self { + f32::from_bits((v & 0xFFFFFFFF) as u32) + } +} + +impl Float for f64 { type Int = u64; const INFINITY: Self = Self::INFINITY; @@ -323,25 +278,6 @@ impl RawFloat for f64 { const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 23; const SMALLEST_POWER_OF_TEN: i32 = -342; - #[inline] - fn from_u64(v: u64) -> Self { - debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); - v as _ - } - - #[inline] - fn from_u64_bits(v: u64) -> Self { - f64::from_bits(v) - } - - fn pow10_fast_path(exponent: usize) -> Self { - const TABLE: [f64; 32] = [ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, - 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 0., 0., 0., 0., 0., 0., 0., 0., 0., - ]; - TABLE[exponent & 31] - } - fn to_bits(self) -> Self::Int { self.to_bits() } @@ -350,3 +286,10 @@ impl RawFloat for f64 { self.classify() } } + +impl FloatExt for f64 { + #[inline] + fn from_u64_bits(v: u64) -> Self { + f64::from_bits(v) + } +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 72112f8b01133..b3fd53cbb9dce 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -88,6 +88,7 @@ #![feature(next_index)] #![feature(non_exhaustive_omitted_patterns_lint)] #![feature(nonzero_from_str_radix)] +#![feature(num_internals)] #![feature(numfmt)] #![feature(one_sided_range)] #![feature(panic_internals)] diff --git a/library/coretests/tests/num/dec2flt/float.rs b/library/coretests/tests/num/dec2flt/float.rs index 25e12435b4728..0713c5c651fb3 100644 --- a/library/coretests/tests/num/dec2flt/float.rs +++ b/library/coretests/tests/num/dec2flt/float.rs @@ -1,4 +1,5 @@ -use core::num::imp::dec2flt::float::RawFloat; +use core::num::imp::dec2flt::Lemire; +use core::num::imp::{Float, FloatExt}; use crate::num::{ldexp_f32, ldexp_f64}; @@ -56,57 +57,60 @@ fn test_f64_integer_decode() { #[test] #[cfg(target_has_reliable_f16)] fn test_f16_consts() { - assert_eq!(::INFINITY, f16::INFINITY); - assert_eq!(::NEG_INFINITY, -f16::INFINITY); - assert_eq!(::NAN.to_bits(), f16::NAN.to_bits()); - assert_eq!(::NEG_NAN.to_bits(), (-f16::NAN).to_bits()); - assert_eq!(::SIG_BITS, 10); - assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -22); - assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 5); - assert_eq!(::MIN_EXPONENT_FAST_PATH, -4); - assert_eq!(::MAX_EXPONENT_FAST_PATH, 4); - assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 7); - assert_eq!(::EXP_MIN, -14); - assert_eq!(::EXP_SAT, 0x1f); - assert_eq!(::SMALLEST_POWER_OF_TEN, -27); - assert_eq!(::LARGEST_POWER_OF_TEN, 4); - assert_eq!(::MAX_MANTISSA_FAST_PATH, 2048); + assert_eq!(::INFINITY, f16::INFINITY); + assert_eq!(::NEG_INFINITY, -f16::INFINITY); + assert_eq!(::NAN.to_bits(), f16::NAN.to_bits()); + assert_eq!(::NEG_NAN.to_bits(), (-f16::NAN).to_bits()); + assert_eq!(::SIG_BITS, 10); + assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -22); + assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 5); + assert_eq!(::EXP_MIN, -14); + assert_eq!(::EXP_SAT, 0x1f); + assert_eq!(::SMALLEST_POWER_OF_TEN, -27); + assert_eq!(::LARGEST_POWER_OF_TEN, 4); + + assert_eq!(::MIN_EXPONENT_FAST_PATH, -4); + assert_eq!(::MAX_EXPONENT_FAST_PATH, 4); + assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 7); + assert_eq!(::MAX_MANTISSA_FAST_PATH, 2048); } #[test] fn test_f32_consts() { - assert_eq!(::INFINITY, f32::INFINITY); - assert_eq!(::NEG_INFINITY, -f32::INFINITY); - assert_eq!(::NAN.to_bits(), f32::NAN.to_bits()); - assert_eq!(::NEG_NAN.to_bits(), (-f32::NAN).to_bits()); - assert_eq!(::SIG_BITS, 23); - assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -17); - assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 10); - assert_eq!(::MIN_EXPONENT_FAST_PATH, -10); - assert_eq!(::MAX_EXPONENT_FAST_PATH, 10); - assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 17); - assert_eq!(::EXP_MIN, -126); - assert_eq!(::EXP_SAT, 0xff); - assert_eq!(::SMALLEST_POWER_OF_TEN, -65); - assert_eq!(::LARGEST_POWER_OF_TEN, 38); - assert_eq!(::MAX_MANTISSA_FAST_PATH, 16777216); + assert_eq!(::INFINITY, f32::INFINITY); + assert_eq!(::NEG_INFINITY, -f32::INFINITY); + assert_eq!(::NAN.to_bits(), f32::NAN.to_bits()); + assert_eq!(::NEG_NAN.to_bits(), (-f32::NAN).to_bits()); + assert_eq!(::SIG_BITS, 23); + assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -17); + assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 10); + assert_eq!(::EXP_MIN, -126); + assert_eq!(::EXP_SAT, 0xff); + assert_eq!(::SMALLEST_POWER_OF_TEN, -65); + assert_eq!(::LARGEST_POWER_OF_TEN, 38); + + assert_eq!(::MIN_EXPONENT_FAST_PATH, -10); + assert_eq!(::MAX_EXPONENT_FAST_PATH, 10); + assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 17); + assert_eq!(::MAX_MANTISSA_FAST_PATH, 16777216); } #[test] fn test_f64_consts() { - assert_eq!(::INFINITY, f64::INFINITY); - assert_eq!(::NEG_INFINITY, -f64::INFINITY); - assert_eq!(::NAN.to_bits(), f64::NAN.to_bits()); - assert_eq!(::NEG_NAN.to_bits(), (-f64::NAN).to_bits()); - assert_eq!(::SIG_BITS, 52); - assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -4); - assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 23); - assert_eq!(::MIN_EXPONENT_FAST_PATH, -22); - assert_eq!(::MAX_EXPONENT_FAST_PATH, 22); - assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 37); - assert_eq!(::EXP_MIN, -1022); - assert_eq!(::EXP_SAT, 0x7ff); - assert_eq!(::SMALLEST_POWER_OF_TEN, -342); - assert_eq!(::LARGEST_POWER_OF_TEN, 308); - assert_eq!(::MAX_MANTISSA_FAST_PATH, 9007199254740992); + assert_eq!(::INFINITY, f64::INFINITY); + assert_eq!(::NEG_INFINITY, -f64::INFINITY); + assert_eq!(::NAN.to_bits(), f64::NAN.to_bits()); + assert_eq!(::NEG_NAN.to_bits(), (-f64::NAN).to_bits()); + assert_eq!(::SIG_BITS, 52); + assert_eq!(::MIN_EXPONENT_ROUND_TO_EVEN, -4); + assert_eq!(::MAX_EXPONENT_ROUND_TO_EVEN, 23); + assert_eq!(::EXP_MIN, -1022); + assert_eq!(::EXP_SAT, 0x7ff); + assert_eq!(::SMALLEST_POWER_OF_TEN, -342); + assert_eq!(::LARGEST_POWER_OF_TEN, 308); + + assert_eq!(::MIN_EXPONENT_FAST_PATH, -22); + assert_eq!(::MAX_EXPONENT_FAST_PATH, 22); + assert_eq!(::MAX_EXPONENT_DISGUISED_FAST_PATH, 37); + assert_eq!(::MAX_MANTISSA_FAST_PATH, 9007199254740992); } diff --git a/library/coretests/tests/num/dec2flt/lemire.rs b/library/coretests/tests/num/dec2flt/lemire.rs index e4ce533ba44da..e5a7ae346f425 100644 --- a/library/coretests/tests/num/dec2flt/lemire.rs +++ b/library/coretests/tests/num/dec2flt/lemire.rs @@ -1,6 +1,5 @@ -use core::num::imp::dec2flt; +use core::num::imp::{Float, dec2flt}; -use dec2flt::float::RawFloat; use dec2flt::lemire::compute_float; #[cfg(target_has_reliable_f16)] diff --git a/library/std/build.rs b/library/std/build.rs index c0a6e30b38082..5f2e441bf7d83 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -79,4 +79,28 @@ fn main() { println!("cargo:rustc-cfg=backtrace_in_libstd"); println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap()); + + println!("cargo:rustc-check-cfg=cfg(vxworks_lt_25_09)"); + + if target_os == "vxworks" { + match vxworks_version_code() { + Some((major, minor)) if (major, minor) < (25, 9) => { + println!("cargo:rustc-cfg=vxworks_lt_25_09"); + } + _ => {} + } + } +} + +/// Retrieve the VxWorks release version from the environment variable set by the VxWorks build +/// environment, in `(minor, patch)` form. +fn vxworks_version_code() -> Option<(u32, u32)> { + let version = env::var("WIND_RELEASE_ID").ok()?; + + let mut pieces = version.trim().split(['.']); + + let major: u32 = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + let minor: u32 = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + + Some((major, minor)) } diff --git a/library/std/src/os/vxworks/fs.rs b/library/std/src/os/vxworks/fs.rs index b88ed19b067a5..a21748ce9fe00 100644 --- a/library/std/src/os/vxworks/fs.rs +++ b/library/std/src/os/vxworks/fs.rs @@ -69,24 +69,54 @@ impl MetadataExt for Metadata { fn st_size(&self) -> u64 { self.as_inner().as_inner().st_size as u64 } + #[cfg(vxworks_lt_25_09)] fn st_atime(&self) -> i64 { self.as_inner().as_inner().st_atime as i64 } + #[cfg(not(vxworks_lt_25_09))] + fn st_atime(&self) -> i64 { + self.as_inner().as_inner().st_atim.tv_sec as i64 + } + #[cfg(vxworks_lt_25_09)] fn st_atime_nsec(&self) -> i64 { 0 } + #[cfg(not(vxworks_lt_25_09))] + fn st_atime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_atim.tv_nsec as i64 + } + #[cfg(vxworks_lt_25_09)] fn st_mtime(&self) -> i64 { self.as_inner().as_inner().st_mtime as i64 } + #[cfg(not(vxworks_lt_25_09))] + fn st_mtime(&self) -> i64 { + self.as_inner().as_inner().st_mtim.tv_sec as i64 + } + #[cfg(vxworks_lt_25_09)] fn st_mtime_nsec(&self) -> i64 { 0 } + #[cfg(not(vxworks_lt_25_09))] + fn st_mtime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_mtim.tv_nsec as i64 + } + #[cfg(vxworks_lt_25_09)] fn st_ctime(&self) -> i64 { self.as_inner().as_inner().st_ctime as i64 } + #[cfg(not(vxworks_lt_25_09))] + fn st_ctime(&self) -> i64 { + self.as_inner().as_inner().st_ctim.tv_sec as i64 + } + #[cfg(vxworks_lt_25_09)] fn st_ctime_nsec(&self) -> i64 { 0 } + #[cfg(not(vxworks_lt_25_09))] + fn st_ctime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_ctim.tv_nsec as i64 + } fn st_blksize(&self) -> u64 { self.as_inner().as_inner().st_blksize as u64 } diff --git a/library/std/src/sync/mpmc/mod.rs b/library/std/src/sync/mpmc/mod.rs index 8df81a580f7b8..16ae8a88370be 100644 --- a/library/std/src/sync/mpmc/mod.rs +++ b/library/std/src/sync/mpmc/mod.rs @@ -623,6 +623,33 @@ impl Sender { _ => false, } } + + /// Returns `true` if the channel is disconnected. + /// + /// Note that a return value of `false` does not guarantee the channel will + /// remain connected. The channel may be disconnected immediately after this method + /// returns, so a subsequent [`Sender::send`] may still fail with [`SendError`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(mpmc_channel)] + /// + /// use std::sync::mpmc::channel; + /// + /// let (tx, rx) = channel::(); + /// assert!(!tx.is_disconnected()); + /// drop(rx); + /// assert!(tx.is_disconnected()); + /// ``` + #[unstable(feature = "mpmc_channel", issue = "126840")] + pub fn is_disconnected(&self) -> bool { + match &self.flavor { + SenderFlavor::Array(chan) => chan.is_disconnected(), + SenderFlavor::List(chan) => chan.is_disconnected(), + SenderFlavor::Zero(chan) => chan.is_disconnected(), + } + } } #[unstable(feature = "mpmc_channel", issue = "126840")] @@ -1349,6 +1376,33 @@ impl Receiver { pub fn iter(&self) -> Iter<'_, T> { Iter { rx: self } } + + /// Returns `true` if the channel is disconnected. + /// + /// Note that a return value of `false` does not guarantee the channel will + /// remain connected. The channel may be disconnected immediately after this method + /// returns, so a subsequent [`Receiver::recv`] may still fail with [`RecvError`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(mpmc_channel)] + /// + /// use std::sync::mpmc::channel; + /// + /// let (tx, rx) = channel::(); + /// assert!(!rx.is_disconnected()); + /// drop(tx); + /// assert!(rx.is_disconnected()); + /// ``` + #[unstable(feature = "mpmc_channel", issue = "126840")] + pub fn is_disconnected(&self) -> bool { + match &self.flavor { + ReceiverFlavor::Array(chan) => chan.is_disconnected(), + ReceiverFlavor::List(chan) => chan.is_disconnected(), + ReceiverFlavor::Zero(chan) => chan.is_disconnected(), + } + } } #[unstable(feature = "mpmc_channel", issue = "126840")] diff --git a/library/std/src/sync/mpmc/zero.rs b/library/std/src/sync/mpmc/zero.rs index f1ecf80fcb9f6..c743462501922 100644 --- a/library/std/src/sync/mpmc/zero.rs +++ b/library/std/src/sync/mpmc/zero.rs @@ -316,4 +316,10 @@ impl Channel { pub(crate) fn is_full(&self) -> bool { true } + + /// Returns `true` if the channel is disconnected. + pub(crate) fn is_disconnected(&self) -> bool { + let inner = self.inner.lock().unwrap(); + inner.is_disconnected + } } diff --git a/library/std/src/sync/mpsc.rs b/library/std/src/sync/mpsc.rs index 0ae23f6e13bf2..a1c49bb83010c 100644 --- a/library/std/src/sync/mpsc.rs +++ b/library/std/src/sync/mpsc.rs @@ -607,6 +607,29 @@ impl Sender { pub fn send(&self, t: T) -> Result<(), SendError> { self.inner.send(t) } + + /// Returns `true` if the channel is disconnected. + /// + /// Note that a return value of `false` does not guarantee the channel will + /// remain connected. The channel may be disconnected immediately after this method + /// returns, so a subsequent [`Sender::send`] may still fail with [`SendError`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(mpsc_is_disconnected)] + /// + /// use std::sync::mpsc::channel; + /// + /// let (tx, rx) = channel::(); + /// assert!(!tx.is_disconnected()); + /// drop(rx); + /// assert!(tx.is_disconnected()); + /// ``` + #[unstable(feature = "mpsc_is_disconnected", issue = "153668")] + pub fn is_disconnected(&self) -> bool { + self.inner.is_disconnected() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1038,6 +1061,29 @@ impl Receiver { pub fn try_iter(&self) -> TryIter<'_, T> { TryIter { rx: self } } + + /// Returns `true` if the channel is disconnected. + /// + /// Note that a return value of `false` does not guarantee the channel will + /// remain connected. The channel may be disconnected immediately after this method + /// returns, so a subsequent [`Receiver::recv`] may still fail with [`RecvError`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(mpsc_is_disconnected)] + /// + /// use std::sync::mpsc::channel; + /// + /// let (tx, rx) = channel::(); + /// assert!(!rx.is_disconnected()); + /// drop(tx); + /// assert!(rx.is_disconnected()); + /// ``` + #[unstable(feature = "mpsc_is_disconnected", issue = "153668")] + pub fn is_disconnected(&self) -> bool { + self.inner.is_disconnected() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 7db474544f04a..2a8571871b732 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -634,7 +634,7 @@ impl FileAttr { } #[cfg(any( - target_os = "vxworks", + all(target_os = "vxworks", vxworks_lt_25_09), target_os = "espidf", target_os = "vita", target_os = "rtems", @@ -643,7 +643,12 @@ impl FileAttr { SystemTime::new(self.stat.st_mtime as i64, 0) } - #[cfg(any(target_os = "horizon", target_os = "hurd", target_os = "nuttx"))] + #[cfg(any( + target_os = "horizon", + target_os = "hurd", + target_os = "nuttx", + all(target_os = "vxworks", not(vxworks_lt_25_09)) + ))] pub fn modified(&self) -> io::Result { SystemTime::new(self.stat.st_mtim.tv_sec as i64, self.stat.st_mtim.tv_nsec as i64) } @@ -669,7 +674,7 @@ impl FileAttr { } #[cfg(any( - target_os = "vxworks", + all(target_os = "vxworks", vxworks_lt_25_09), target_os = "espidf", target_os = "vita", target_os = "rtems" @@ -678,7 +683,12 @@ impl FileAttr { SystemTime::new(self.stat.st_atime as i64, 0) } - #[cfg(any(target_os = "horizon", target_os = "hurd", target_os = "nuttx"))] + #[cfg(any( + target_os = "horizon", + target_os = "hurd", + target_os = "nuttx", + all(target_os = "vxworks", not(vxworks_lt_25_09)) + ))] pub fn accessed(&self) -> io::Result { SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64) } diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index f4e6a20ec8497..85c23ac18e763 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -5,14 +5,17 @@ //! allows setting up things that cannot be simply captured inside the bootstrap.toml, in addition to //! leading people away from manually editing most of the bootstrap.toml values. +use std::collections::BTreeMap; use std::env::consts::EXE_SUFFIX; use std::fmt::Write as _; use std::fs::File; use std::io::Write; use std::path::{MAIN_SEPARATOR_STR, Path, PathBuf}; use std::str::FromStr; +use std::sync::LazyLock; use std::{fmt, fs, io}; +use serde_derive::{Deserialize, Serialize}; use sha2::Digest; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; @@ -529,7 +532,8 @@ undesirable, simply delete the `pre-push` file from .git/hooks." } /// Handles editor-specific setup differences -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] enum EditorKind { Emacs, Helix, @@ -538,6 +542,13 @@ enum EditorKind { Zed, } +static PARSED_HASHES: LazyLock>> = LazyLock::new(|| { + const ALL_HASHES: &str = include_str!("setup/hashes.json"); + let mut map: BTreeMap<_, Vec<_>> = serde_json::from_str(ALL_HASHES).unwrap(); + map.insert(EditorKind::Vim, map.get(&EditorKind::VsCode).unwrap().clone()); + map +}); + impl EditorKind { // Used in `./tests.rs`. #[cfg(test)] @@ -588,59 +599,7 @@ Select which editor you would like to set up [default: None]: "; /// New entries should be appended whenever this is updated so we can detect /// outdated vs. user-modified settings files. fn hashes(&self) -> &'static [&'static str] { - match self { - EditorKind::Emacs => &[ - "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", - "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45", - "b5dd299b93dca3ceeb9b335f929293cb3d4bf4977866fbe7ceeac2a8a9f99088", - "631c837b0e98ae35fd48b0e5f743b1ca60adadf2d0a2b23566ba25df372cf1a9", - "080955765db84bb6cbf178879f489c4e2369397626a6ecb3debedb94a9d0b3ce", - "f501475c6654187091c924ae26187fa5791d74d4a8ab3fb61fbbe4c0275aade1", - "54bc48fe1996177f5eef86d7231b33978e6d8b737cb0a899e622b7e975c95308", - "08d30e455ceec6e01d9bcef8b9449f2ddd14d278ca8627cdad90e02d9f44e938", - ], - EditorKind::Helix => &[ - "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", - "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040", - "f252dcc30ca85a193a699581e5e929d5bd6c19d40d7a7ade5e257a9517a124a5", - "198c195ed0c070d15907b279b8b4ea96198ca71b939f5376454f3d636ab54da5", - "1c43ead340b20792b91d02b08494ee68708e7e09f56b6766629b4b72079208f1", - "eec09a09452682060afd23dd5d3536ccac5615b3cdbf427366446901215fb9f6", - "cb653043852d9d5ff4a5be56407b859ff9928be055ad3f307eb309aad04765e6", - "e28b1930d16d3d8bbdeed7bd4a995613e648b49e08c9b6f5271880f520637fed", - ], - EditorKind::Vim | EditorKind::VsCode => &[ - "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", - "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922", - "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0", - "3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541", - "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923", - "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", - "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", - "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", - "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", - "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", - "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", - "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", - "701b73751efd7abd6487f2c79348dab698af7ac4427b79fa3d2087c867144b12", - "a61df796c0c007cb6512127330564e49e57d558dec715703916a928b072a1054", - "02a49ac2d31f00ef6e4531c44e00dac51cea895112e480553f1ba060b3942a47", - "0aa4748848de0d1cb7ece92a0123c8897fef6de2f58aff8fda1426f098b7a798", - "e5e357862e5d6d0d9da335e9823c07b8a7dc42bbf18d72cc5206ad1049cd8fcc", - "a68fd5828e75f3e921f265e29ce1e9efa554083c3773fdb4b8e1ab3b2d9dc6cd", - ], - EditorKind::Zed => &[ - "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c", - "a5380cf5dd9328731aecc5dfb240d16dac46ed272126b9728006151ef42f5909", - "2e96bf0d443852b12f016c8fc9840ab3d0a2b4fe0b0fb3a157e8d74d5e7e0e26", - "4fadd4c87389a601a27db0d3d74a142fa3a2e656ae78982e934dbe24bee32ad6", - "f0bb3d23ab1a49175ab0ef5c4071af95bb03d01d460776cdb716d91333443382", - "5ef83292111d9a8bb63b6afc3abf42d0bc78fe24985f0d2e039e73258b5dab8f", - "74420c13094b530a986b37c4f1d23cb58c0e8e2295f5858ded129fb1574e66f9", - "2d3b592c089b2ad2c528686a1e371af49922edad1c59accd5d5f31612a441568", - "0767a2398ccc253274b184adbb9e018ce931bd0ef45baad06dad19b652c52951", - ], - } + PARSED_HASHES.get(self).unwrap() } fn settings_path(&self, config: &Config) -> PathBuf { diff --git a/src/bootstrap/src/core/build_steps/setup/hashes.json b/src/bootstrap/src/core/build_steps/setup/hashes.json new file mode 100644 index 0000000000000..067c8fffe0d50 --- /dev/null +++ b/src/bootstrap/src/core/build_steps/setup/hashes.json @@ -0,0 +1,73 @@ +{ + "emacs": [ + "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", + "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45", + "b5dd299b93dca3ceeb9b335f929293cb3d4bf4977866fbe7ceeac2a8a9f99088", + "631c837b0e98ae35fd48b0e5f743b1ca60adadf2d0a2b23566ba25df372cf1a9", + "080955765db84bb6cbf178879f489c4e2369397626a6ecb3debedb94a9d0b3ce", + "f501475c6654187091c924ae26187fa5791d74d4a8ab3fb61fbbe4c0275aade1", + "54bc48fe1996177f5eef86d7231b33978e6d8b737cb0a899e622b7e975c95308", + "08d30e455ceec6e01d9bcef8b9449f2ddd14d278ca8627cdad90e02d9f44e938" + ], + "helix": [ + "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", + "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040", + "f252dcc30ca85a193a699581e5e929d5bd6c19d40d7a7ade5e257a9517a124a5", + "198c195ed0c070d15907b279b8b4ea96198ca71b939f5376454f3d636ab54da5", + "1c43ead340b20792b91d02b08494ee68708e7e09f56b6766629b4b72079208f1", + "eec09a09452682060afd23dd5d3536ccac5615b3cdbf427366446901215fb9f6", + "cb653043852d9d5ff4a5be56407b859ff9928be055ad3f307eb309aad04765e6", + "e28b1930d16d3d8bbdeed7bd4a995613e648b49e08c9b6f5271880f520637fed" + ], + "vim": [ + "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", + "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922", + "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0", + "3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541", + "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923", + "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", + "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", + "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", + "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", + "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", + "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", + "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", + "701b73751efd7abd6487f2c79348dab698af7ac4427b79fa3d2087c867144b12", + "a61df796c0c007cb6512127330564e49e57d558dec715703916a928b072a1054", + "02a49ac2d31f00ef6e4531c44e00dac51cea895112e480553f1ba060b3942a47", + "0aa4748848de0d1cb7ece92a0123c8897fef6de2f58aff8fda1426f098b7a798", + "e5e357862e5d6d0d9da335e9823c07b8a7dc42bbf18d72cc5206ad1049cd8fcc", + "a68fd5828e75f3e921f265e29ce1e9efa554083c3773fdb4b8e1ab3b2d9dc6cd" + ], + "vscode": [ + "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", + "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922", + "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0", + "3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541", + "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923", + "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", + "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", + "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", + "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", + "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", + "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", + "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", + "701b73751efd7abd6487f2c79348dab698af7ac4427b79fa3d2087c867144b12", + "a61df796c0c007cb6512127330564e49e57d558dec715703916a928b072a1054", + "02a49ac2d31f00ef6e4531c44e00dac51cea895112e480553f1ba060b3942a47", + "0aa4748848de0d1cb7ece92a0123c8897fef6de2f58aff8fda1426f098b7a798", + "e5e357862e5d6d0d9da335e9823c07b8a7dc42bbf18d72cc5206ad1049cd8fcc", + "a68fd5828e75f3e921f265e29ce1e9efa554083c3773fdb4b8e1ab3b2d9dc6cd" + ], + "zed": [ + "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c", + "a5380cf5dd9328731aecc5dfb240d16dac46ed272126b9728006151ef42f5909", + "2e96bf0d443852b12f016c8fc9840ab3d0a2b4fe0b0fb3a157e8d74d5e7e0e26", + "4fadd4c87389a601a27db0d3d74a142fa3a2e656ae78982e934dbe24bee32ad6", + "f0bb3d23ab1a49175ab0ef5c4071af95bb03d01d460776cdb716d91333443382", + "5ef83292111d9a8bb63b6afc3abf42d0bc78fe24985f0d2e039e73258b5dab8f", + "74420c13094b530a986b37c4f1d23cb58c0e8e2295f5858ded129fb1574e66f9", + "2d3b592c089b2ad2c528686a1e371af49922edad1c59accd5d5f31612a441568", + "0767a2398ccc253274b184adbb9e018ce931bd0ef45baad06dad19b652c52951" + ] +} diff --git a/src/bootstrap/src/core/build_steps/setup/tests.rs b/src/bootstrap/src/core/build_steps/setup/tests.rs index e8f83ff75e404..57b5492866614 100644 --- a/src/bootstrap/src/core/build_steps/setup/tests.rs +++ b/src/bootstrap/src/core/build_steps/setup/tests.rs @@ -1,3 +1,8 @@ +use std::collections::BTreeMap; +use std::fs::File; +use std::io::Write; +use std::path::Path; + use sha2::Digest; use super::EditorKind; @@ -5,16 +10,41 @@ use crate::utils::helpers::hex_encode; #[test] fn check_matching_settings_hash() { + // Needs to be a btree so we serialize in a deterministic order. + let mut mismatched = BTreeMap::new(); + for editor in EditorKind::ALL { let mut hasher = sha2::Sha256::new(); hasher.update(&editor.settings_template()); - let hash = hex_encode(hasher.finalize().as_slice()); - assert_eq!( - &hash, - editor.hashes().last().unwrap(), - "Update `EditorKind::hashes()` with the new hash of `{}` for `EditorKind::{:?}`", - editor.settings_template(), - editor, - ); + let actual = hex_encode(hasher.finalize().as_slice()); + let expected = *editor.hashes().last().unwrap(); + + if expected != actual { + mismatched.insert(editor, (expected, actual)); + } + } + + if mismatched.is_empty() { + return; + } + + if option_env!("INSTA_UPDATE").is_some_and(|s| s != "0") { + let mut updated = super::PARSED_HASHES.clone(); + for (editor, (_, actual)) in &mismatched { + *updated.get_mut(editor).unwrap().last_mut().unwrap() = actual; + } + let hash_path = + Path::new(env!("CARGO_MANIFEST_DIR")).join("src/core/build_steps/setup/hashes.json"); + let mut hash_file = File::create(hash_path).unwrap(); + serde_json::to_writer_pretty(&mut hash_file, &updated).unwrap(); + hash_file.write_all(b"\n").unwrap(); + } else { + for (editor, (expected, actual)) in &mismatched { + eprintln!("recorded hash did not match actual hash: {expected} != {actual}"); + eprintln!( + "Run `x test --bless -- hash`, or manually update `setup/hashes.json` with the new hash of `{actual}` for `EditorKind::{editor:?}`" + ); + } + panic!("mismatched hashes"); } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 7be45c5fa9d40..397bb7054a617 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -903,6 +903,58 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct StdarchVerify { + build_compiler: Compiler, + target: TargetSelection, +} + +impl Step for StdarchVerify { + type Output = (); + const IS_HOST: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("library/stdarch/crates/stdarch-verify") + } + + fn is_default_step(_builder: &Builder<'_>) -> bool { + true + } + + fn make_run(run: RunConfig<'_>) { + let builder = run.builder; + let build_compiler = get_compiler_to_test(builder, run.target); + builder.ensure(StdarchVerify { build_compiler, target: run.target }); + } + + fn run(self, builder: &Builder<'_>) { + let build_compiler = self.build_compiler; + let target = self.target; + + builder.std(build_compiler, target); + + let cargo = tool::prepare_tool_cargo( + builder, + build_compiler, + Mode::ToolStd, + target, + Kind::Test, + "library/stdarch/crates/stdarch-verify", + SourceType::InTree, + &[], + ); + + run_cargo_test( + cargo, + &[], + &["stdarch-verify".to_string()], + Some("stdarch-verify"), + target, + builder, + ); + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Clippy { compilers: RustcPrivateCompilers, diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap index ac2f315d39d96..e4c467161ba1a 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap @@ -182,6 +182,9 @@ expression: test [Test] test::RustcBook targets: [x86_64-unknown-linux-gnu] - Set({test::src/doc/rustc}) +[Test] test::StdarchVerify + targets: [x86_64-unknown-linux-gnu] + - Set({test::library/stdarch/crates/stdarch-verify}) [Test] test::RustdocJSStd targets: [x86_64-unknown-linux-gnu] - Suite(test::tests/rustdoc-js-std) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_library.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_library.snap index dfc397597a877..f97bb839c1e73 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_library.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_library.snap @@ -18,3 +18,6 @@ expression: test library - Set({test::library/sysroot}) - Set({test::library/test}) - Set({test::library/unwind}) +[Test] test::StdarchVerify + targets: [x86_64-unknown-linux-gnu] + - Set({test::library/stdarch/crates/stdarch-verify}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap index 09adbb0041ae6..5ff4ea089a539 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap @@ -181,6 +181,9 @@ expression: test --skip=coverage [Test] test::RustcBook targets: [x86_64-unknown-linux-gnu] - Set({test::src/doc/rustc}) +[Test] test::StdarchVerify + targets: [x86_64-unknown-linux-gnu] + - Set({test::library/stdarch/crates/stdarch-verify}) [Test] test::RustdocJSStd targets: [x86_64-unknown-linux-gnu] - Suite(test::tests/rustdoc-js-std) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap index b5fccfcb966bb..fbbe2d5979a7b 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap @@ -145,6 +145,9 @@ expression: test --skip=tests [Test] test::RustcBook targets: [x86_64-unknown-linux-gnu] - Set({test::src/doc/rustc}) +[Test] test::StdarchVerify + targets: [x86_64-unknown-linux-gnu] + - Set({test::library/stdarch/crates/stdarch-verify}) [Test] test::RustdocTheme targets: [x86_64-unknown-linux-gnu] - Set({test::src/tools/rustdoc-themes}) diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index ae91b20406295..222c4f39341f6 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -894,6 +894,7 @@ impl<'a> Builder<'a> { test::CargoMiri, test::Clippy, test::CompiletestTest, + test::StdarchVerify, test::CrateRunMakeSupport, test::CrateBuildHelper, test::RustdocJSStd, diff --git a/src/bootstrap/src/core/config/target_selection.rs b/src/bootstrap/src/core/config/target_selection.rs index 47f6d6f386dfb..8457607b897dd 100644 --- a/src/bootstrap/src/core/config/target_selection.rs +++ b/src/bootstrap/src/core/config/target_selection.rs @@ -142,7 +142,7 @@ impl SplitDebuginfo { pub fn default_for_platform(target: TargetSelection) -> Self { if target.contains("apple") { SplitDebuginfo::Unpacked - } else if target.is_windows() { + } else if target.is_msvc() { SplitDebuginfo::Packed } else { SplitDebuginfo::Off diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index b264c961b6593..f9b0d2dbb2095 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -7,6 +7,7 @@ //! relevant to command execution in the bootstrap process. This includes settings such as //! dry-run mode, verbosity level, and failure behavior. +use std::backtrace::{Backtrace, BacktraceStatus}; use std::collections::HashMap; use std::ffi::{OsStr, OsString}; use std::fmt::{Debug, Formatter}; @@ -930,6 +931,16 @@ Executed at: {executed_at}"#, if stderr.captures() { writeln!(error_message, "\n--- STDERR vvv\n{}", output.stderr().trim()).unwrap(); } + let backtrace = if exec_ctx.verbosity > 1 { + Backtrace::force_capture() + } else if matches!(command.failure_behavior, BehaviorOnFailure::Ignore) { + Backtrace::disabled() + } else { + Backtrace::capture() + }; + if matches!(backtrace.status(), BacktraceStatus::Captured) { + writeln!(error_message, "\n--- BACKTRACE vvv\n{backtrace}").unwrap(); + } match command.failure_behavior { BehaviorOnFailure::DelayFail => { diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-22/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-22/Dockerfile new file mode 100644 index 0000000000000..a22e8de90804f --- /dev/null +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-22/Dockerfile @@ -0,0 +1,66 @@ +FROM ubuntu:26.04 + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + bzip2 \ + g++ \ + gcc-multilib \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + git \ + cmake \ + sudo \ + gdb \ + llvm-22-tools \ + llvm-22-dev \ + libedit-dev \ + libssl-dev \ + pkg-config \ + zlib1g-dev \ + xz-utils \ + nodejs \ + mingw-w64 \ + # libgccjit dependencies + flex \ + libmpfr-dev \ + libgmp-dev \ + libmpc3 \ + libmpc-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install powershell (universal package) so we can test x.ps1 on Linux +# FIXME: need a "universal" version that supports libicu74, but for now it still works to ignore that dep. +RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \ + dpkg --ignore-depends=libicu72 -i powershell.deb && \ + rm -f powershell.deb + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# We are disabling CI LLVM since this builder is intentionally using a host +# LLVM, rather than the typical src/llvm-project LLVM. +ENV NO_DOWNLOAD_CI_LLVM 1 +ENV EXTERNAL_LLVM 1 + +# Using llvm-link-shared due to libffi issues -- see #34486 +ENV RUST_CONFIGURE_ARGS \ + --build=x86_64-unknown-linux-gnu \ + --llvm-root=/usr/lib/llvm-22 \ + --enable-llvm-link-shared \ + --set rust.randomize-layout=true \ + --set rust.thin-lto-import-instr-limit=10 + +COPY scripts/shared.sh /scripts/ + +COPY scripts/x86_64-gnu-llvm.sh /scripts/ +COPY scripts/x86_64-gnu-llvm2.sh /scripts/ +COPY scripts/x86_64-gnu-llvm3.sh /scripts/ +COPY scripts/stage_2_test_set1.sh /scripts/ +COPY scripts/stage_2_test_set2.sh /scripts/ + +ENV SCRIPT "Must specify DOCKER_SCRIPT for this image" diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index a70e4acf94a36..7c0f1d3f29305 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -406,6 +406,31 @@ auto: DOCKER_SCRIPT: x86_64-gnu-llvm3.sh <<: *job-linux-4c + # The x86_64-gnu-llvm-22 job is split into multiple jobs to run tests in parallel. + # x86_64-gnu-llvm-22-1 skips tests that run in x86_64-gnu-llvm-22-{2,3}. + - name: x86_64-gnu-llvm-22-1 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-22 + DOCKER_SCRIPT: stage_2_test_set2.sh + <<: *job-linux-4c + + # Skip tests that run in x86_64-gnu-llvm-22-{1,3} + - name: x86_64-gnu-llvm-22-2 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-22 + DOCKER_SCRIPT: x86_64-gnu-llvm2.sh + <<: *job-linux-4c + + # Skip tests that run in x86_64-gnu-llvm-22-{1,2} + - name: x86_64-gnu-llvm-22-3 + env: + RUST_BACKTRACE: 1 + IMAGE: x86_64-gnu-llvm-22 + DOCKER_SCRIPT: x86_64-gnu-llvm3.sh + <<: *job-linux-4c + - name: x86_64-gnu-nopt <<: *job-linux-4c diff --git a/src/doc/rustc/src/platform-support/vxworks.md b/src/doc/rustc/src/platform-support/vxworks.md index 091c757a2ee36..0cf3822f759e7 100644 --- a/src/doc/rustc/src/platform-support/vxworks.md +++ b/src/doc/rustc/src/platform-support/vxworks.md @@ -28,6 +28,12 @@ Target triplets available: The minimum supported version is VxWorks 7. +### Environment + +#### `WIND_RELEASE_ID` + +In VxWorks build environment, the environment variable `WIND_RELEASE_ID` indicates the VxWorks release version used for the build. The `WIND_RELEASE_ID` can be used to conditionally compile features/code or handle version specific behaviour. + ## Building Rust for each target can be cross-compiled with its specific target vsb configuration. Std support is added but not yet fully tested. diff --git a/tests/crashes/147973.rs b/tests/crashes/147973.rs deleted file mode 100644 index 7271c54846f15..0000000000000 --- a/tests/crashes/147973.rs +++ /dev/null @@ -1,14 +0,0 @@ -// This is part of series of regression tests for some diagnostics ICEs encountered in the wild with -// suggestions having overlapping parts under https://github.com/rust-lang/rust/pull/146121. -// This is one MCVE from the beta crater run regressions from issue 147973. - -//@ needs-rustc-debug-assertions -//@ known-bug: #147973 - -//@ aux-build: overlapping_spans_helper.rs -extern crate overlapping_spans_helper; - -fn main() { - let _name = Some(1); - overlapping_spans_helper::do_loop!(_name); -} diff --git a/tests/ui/README.md b/tests/ui/README.md index 45728822b3cf8..b6e6557088922 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -778,10 +778,6 @@ These tests revolve around the `--json` compiler flag. See [JSON Output](https:/ Tests exercising keywords, such as attempting to use them as identifiers when not contextual keywords. -## `tests/ui/kindck/` - -**FIXME**: `kindck` is no longer a thing, these tests probably need to be audited and rehomed. - ## `tests/ui/label/` Exercises block and loop `'label`s. diff --git a/tests/ui/borrowck/kindck-implicit-close-over-mut-var.rs b/tests/ui/borrowck/kindck-implicit-close-over-mut-var.rs deleted file mode 100644 index 22ed8bd3beefa..0000000000000 --- a/tests/ui/borrowck/kindck-implicit-close-over-mut-var.rs +++ /dev/null @@ -1,49 +0,0 @@ -//@ run-pass - -#![allow(unused_must_use)] -#![allow(dead_code)] -use std::thread; - -fn user(_i: isize) {} - -fn foo() { - // Here, i is *copied* into the proc (heap closure). - // Requires allocation. The proc's copy is not mutable. - let mut i = 0; - let t = thread::spawn(move|| { - user(i); - println!("spawned {}", i) - }); - i += 1; - println!("original {}", i); - t.join(); -} - -fn bar() { - // Here, the original i has not been moved, only copied, so is still - // mutable outside of the proc. - let mut i = 0; - while i < 10 { - let t = thread::spawn(move|| { - user(i); - }); - i += 1; - t.join(); - } -} - -fn car() { - // Here, i must be shadowed in the proc to be mutable. - let mut i = 0; - while i < 10 { - let t = thread::spawn(move|| { - let mut i = i; - i += 1; - user(i); - }); - i += 1; - t.join(); - } -} - -pub fn main() {} diff --git a/tests/ui/const-generics/issues/issue-83249.stderr b/tests/ui/const-generics/issues/issue-83249.stderr index 2668348613a40..0f00f70700f52 100644 --- a/tests/ui/const-generics/issues/issue-83249.stderr +++ b/tests/ui/const-generics/issues/issue-83249.stderr @@ -17,10 +17,10 @@ note: required by a bound in `foo` | LL | fn foo(_: [u8; T::N]) -> T { | ^^^ required by this bound in `foo` -help: consider giving this pattern a type +help: consider giving this pattern a type, where the type for type parameter `T` is specified | -LL | let _: /* Type */ = foo([0; 1]); - | ++++++++++++ +LL | let _: u8 = foo([0; 1]); + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/braced-const-infer.rs b/tests/ui/const-generics/mgca/braced-const-infer.rs new file mode 100644 index 0000000000000..9b007d338d1da --- /dev/null +++ b/tests/ui/const-generics/mgca/braced-const-infer.rs @@ -0,0 +1,9 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/153198 +#![feature(min_generic_const_args)] +#![allow(incomplete_features, rust_2021_compatibility)] + +trait Trait {} + +impl dyn Trait<{_}> {} //~ ERROR: the placeholder `_` is not allowed within types on item signatures + +fn main() {} diff --git a/tests/ui/const-generics/mgca/braced-const-infer.stderr b/tests/ui/const-generics/mgca/braced-const-infer.stderr new file mode 100644 index 0000000000000..d8ffee4cd0e8f --- /dev/null +++ b/tests/ui/const-generics/mgca/braced-const-infer.stderr @@ -0,0 +1,9 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for implementations + --> $DIR/braced-const-infer.rs:7:17 + | +LL | impl dyn Trait<{_}> {} + | ^ not allowed in type signatures + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/const-generics/mgca/infer-vars-in-const-args-conflicting.rs b/tests/ui/const-generics/mgca/infer-vars-in-const-args-conflicting.rs new file mode 100644 index 0000000000000..eeb76683eedf1 --- /dev/null +++ b/tests/ui/const-generics/mgca/infer-vars-in-const-args-conflicting.rs @@ -0,0 +1,21 @@ +//! This test ensures compilation failure when trying to pass literals +//! without explicitly stated type as inference variables in generic arguments. +//! +//! See https://github.com/rust-lang/rust/pull/153557 + +#![allow(incomplete_features)] +#![feature(adt_const_params, min_generic_const_args, generic_const_parameter_types)] + +fn main() { + foo::<_, { 2 }>(); + //~^ ERROR: type annotations needed for the literal + let _: PC<_, { 42 }> = PC { a: 1, b: 1 }; + //~^ ERROR: type annotations needed for the literal +} + +struct PC { +//~^ ERROR: `T` can't be used as a const parameter type [E0741] + a: T, +} + +fn foo() {} diff --git a/tests/ui/const-generics/mgca/infer-vars-in-const-args-conflicting.stderr b/tests/ui/const-generics/mgca/infer-vars-in-const-args-conflicting.stderr new file mode 100644 index 0000000000000..a4b13f41aef07 --- /dev/null +++ b/tests/ui/const-generics/mgca/infer-vars-in-const-args-conflicting.stderr @@ -0,0 +1,21 @@ +error[E0741]: `T` can't be used as a const parameter type + --> $DIR/infer-vars-in-const-args-conflicting.rs:16:23 + | +LL | struct PC { + | ^ + +error: type annotations needed for the literal + --> $DIR/infer-vars-in-const-args-conflicting.rs:10:16 + | +LL | foo::<_, { 2 }>(); + | ^ + +error: type annotations needed for the literal + --> $DIR/infer-vars-in-const-args-conflicting.rs:12:20 + | +LL | let _: PC<_, { 42 }> = PC { a: 1, b: 1 }; + | ^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/const-generics/mgca/infer-vars-in-const-args-correct.rs b/tests/ui/const-generics/mgca/infer-vars-in-const-args-correct.rs new file mode 100644 index 0000000000000..f1c0e0b2b4c30 --- /dev/null +++ b/tests/ui/const-generics/mgca/infer-vars-in-const-args-correct.rs @@ -0,0 +1,22 @@ +//! This test ensures no errors are emitted when lowering literals with +//! explicitly stated types and inference variables in the type of the const +//! generic parameter. +//! +//! See https://github.com/rust-lang/rust/pull/153557 + +//@check-pass + +#![allow(incomplete_features)] +#![feature(adt_const_params, + min_generic_const_args, + generic_const_parameter_types, + unsized_const_params +)] + +use std::marker::ConstParamTy_; + +fn main() { + foo::<_, 2_i32>(); +} + +fn foo() {} diff --git a/tests/ui/const-generics/mgca/macro-const-arg-infer.rs b/tests/ui/const-generics/mgca/macro-const-arg-infer.rs new file mode 100644 index 0000000000000..017c63d8b0db5 --- /dev/null +++ b/tests/ui/const-generics/mgca/macro-const-arg-infer.rs @@ -0,0 +1,20 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/153198 +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] +macro_rules! y { + ( $($matcher:tt)*) => { + _ //~ ERROR: the placeholder `_` is not allowed within types on item signatures + }; +} + +struct A; //~ ERROR: type parameter `T` is never used + +const y: A< + { + y! { + x + } + }, +> = 1; //~ ERROR: mismatched types + +fn main() {} diff --git a/tests/ui/const-generics/mgca/macro-const-arg-infer.stderr b/tests/ui/const-generics/mgca/macro-const-arg-infer.stderr new file mode 100644 index 0000000000000..406206c59e18f --- /dev/null +++ b/tests/ui/const-generics/mgca/macro-const-arg-infer.stderr @@ -0,0 +1,44 @@ +error[E0392]: type parameter `T` is never used + --> $DIR/macro-const-arg-infer.rs:10:10 + | +LL | struct A; + | ^ unused type parameter + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead + +error[E0308]: mismatched types + --> $DIR/macro-const-arg-infer.rs:18:5 + | +LL | const y: A< + | __________- +LL | | { +LL | | y! { +LL | | x +LL | | } +LL | | }, +LL | | > = 1; + | | - ^ expected `A<_>`, found integer + | |_| + | expected because of the type of the constant + | + = note: expected struct `A<_>` + found type `{integer}` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/macro-const-arg-infer.rs:6:9 + | +LL | _ + | ^ not allowed in type signatures +... +LL | / y! { +LL | | x +LL | | } + | |_________- in this macro invocation + | + = note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0121, E0308, E0392. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/hygiene/unpretty-debug-lifetimes.stdout b/tests/ui/hygiene/unpretty-debug-lifetimes.stdout index 28a5c70a02d79..689453326c0b5 100644 --- a/tests/ui/hygiene/unpretty-debug-lifetimes.stdout +++ b/tests/ui/hygiene/unpretty-debug-lifetimes.stdout @@ -7,15 +7,17 @@ // Don't break whenever Symbol numbering changes //@ normalize-stdout: "\d+#" -> "0#" -#![feature /* 0#0 */(decl_macro)] -#![feature /* 0#0 */(no_core)] +#![feature /* 0#0 */(decl_macro /* 0#0 */)] +#![feature /* 0#0 */(no_core /* 0#0 */)] #![no_core /* 0#0 */] macro lifetime_hygiene /* 0#0 */ { - ($f:ident<$a:lifetime>) => { fn $f<$a, 'a>() {} } + ($f /* 0#0 */:ident /* 0#0 */<$a /* 0#0 */:lifetime /* 0#0 */>) + => + { fn /* 0#0 */ $f /* 0#0 */<$a /* 0#0 */, 'a /* 0#0 */>() {} } } fn f /* 0#0 */<'a /* 0#0 */, 'a /* 0#1 */>() {} diff --git a/tests/ui/hygiene/unpretty-debug-metavars.rs b/tests/ui/hygiene/unpretty-debug-metavars.rs new file mode 100644 index 0000000000000..41bf75cd0d98b --- /dev/null +++ b/tests/ui/hygiene/unpretty-debug-metavars.rs @@ -0,0 +1,26 @@ +//@ check-pass +//@ compile-flags: -Zunpretty=expanded,hygiene + +// Regression test for token hygiene annotations in -Zunpretty=expanded,hygiene +// Previously, metavar parameters in macro-generated macro_rules! definitions +// were missing hygiene annotations, making identical `$marg` bindings +// indistinguishable. + +// Don't break whenever Symbol numbering changes +//@ normalize-stdout: "\d+#" -> "0#" + +#![feature(no_core)] +#![no_core] + +macro_rules! make_macro { + (@inner $name:ident ($dol:tt) $a:ident) => { + macro_rules! $name { + ($dol $a : expr, $dol marg : expr) => {} + } + }; + ($name:ident) => { + make_macro!{@inner $name ($) marg} + }; +} + +make_macro!(add2); diff --git a/tests/ui/hygiene/unpretty-debug-metavars.stdout b/tests/ui/hygiene/unpretty-debug-metavars.stdout new file mode 100644 index 0000000000000..89658bc909a13 --- /dev/null +++ b/tests/ui/hygiene/unpretty-debug-metavars.stdout @@ -0,0 +1,53 @@ +//@ check-pass +//@ compile-flags: -Zunpretty=expanded,hygiene + +// Regression test for token hygiene annotations in -Zunpretty=expanded,hygiene +// Previously, metavar parameters in macro-generated macro_rules! definitions +// were missing hygiene annotations, making identical `$marg` bindings +// indistinguishable. + +// Don't break whenever Symbol numbering changes +//@ normalize-stdout: "\d+#" -> "0#" + +#![feature /* 0#0 */(no_core /* 0#0 */)] +#![no_core /* 0#0 */] + +macro_rules! make_macro + /* + 0#0 + */ { + (@inner /* 0#0 */ $name /* 0#0 */:ident /* 0#0 + */($dol /* 0#0 */:tt /* 0#0 */) $a /* 0#0 */:ident /* 0#0 */) + => + { + macro_rules /* 0#0 */! $name /* 0#0 */ + { + ($dol /* 0#0 */ $a /* 0#0 */ : expr /* 0#0 */, $dol /* + 0#0 */ marg /* 0#0 */ : expr /* 0#0 */) => {} + } + }; ($name /* 0#0 */:ident /* 0#0 */) => + { + make_macro /* 0#0 + */!{@inner /* 0#0 */ $name /* 0#0 */($) marg /* 0#0 */} + }; +} +macro_rules! add2 + /* + 0#0 + */ { + ($ marg /* 0#1 */ : expr /* 0#2 */, $marg /* 0#2 */ : expr /* + 0#2 */) => {} +} + + +/* +Expansions: +crate0::{{expn0}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Root +crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "make_macro") +crate0::{{expn2}}: parent: crate0::{{expn1}}, call_site_ctxt: #1, def_site_ctxt: #0, kind: Macro(Bang, "make_macro") + +SyntaxContexts: +#0: parent: #0, outer_mark: (crate0::{{expn0}}, Opaque) +#1: parent: #0, outer_mark: (crate0::{{expn1}}, SemiOpaque) +#2: parent: #0, outer_mark: (crate0::{{expn2}}, SemiOpaque) +*/ diff --git a/tests/ui/hygiene/unpretty-debug-shadow.rs b/tests/ui/hygiene/unpretty-debug-shadow.rs new file mode 100644 index 0000000000000..2aa68c8aec110 --- /dev/null +++ b/tests/ui/hygiene/unpretty-debug-shadow.rs @@ -0,0 +1,20 @@ +//@ check-pass +//@ compile-flags: -Zunpretty=expanded,hygiene + +// Regression test for token hygiene annotations in -Zunpretty=expanded,hygiene +// Previously, tokens in macro_rules! bodies were missing hygiene annotations, +// making it impossible to see how a macro's reference to a shadowed variable +// is distinguished from the shadowing binding. + +// Don't break whenever Symbol numbering changes +//@ normalize-stdout: "\d+#" -> "0#" + +#![feature(no_core)] +#![no_core] + +fn f() { + let x = 0; + macro_rules! use_x { () => { x }; } + let x = 1; + use_x!(); +} diff --git a/tests/ui/hygiene/unpretty-debug-shadow.stdout b/tests/ui/hygiene/unpretty-debug-shadow.stdout new file mode 100644 index 0000000000000..36076b6a968fe --- /dev/null +++ b/tests/ui/hygiene/unpretty-debug-shadow.stdout @@ -0,0 +1,30 @@ +//@ check-pass +//@ compile-flags: -Zunpretty=expanded,hygiene + +// Regression test for token hygiene annotations in -Zunpretty=expanded,hygiene +// Previously, tokens in macro_rules! bodies were missing hygiene annotations, +// making it impossible to see how a macro's reference to a shadowed variable +// is distinguished from the shadowing binding. + +// Don't break whenever Symbol numbering changes +//@ normalize-stdout: "\d+#" -> "0#" + +#![feature /* 0#0 */(no_core /* 0#0 */)] +#![no_core /* 0#0 */] + +fn f /* 0#0 */() { + let x /* 0#0 */ = 0; + macro_rules! use_x /* 0#0 */ { () => { x /* 0#0 */ }; } + let x /* 0#0 */ = 1; + x /* 0#1 */; +} + +/* +Expansions: +crate0::{{expn0}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Root +crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "use_x") + +SyntaxContexts: +#0: parent: #0, outer_mark: (crate0::{{expn0}}, Opaque) +#1: parent: #0, outer_mark: (crate0::{{expn1}}, SemiOpaque) +*/ diff --git a/tests/ui/hygiene/unpretty-debug.stdout b/tests/ui/hygiene/unpretty-debug.stdout index f35bd7a7cb2ca..ac6051e2d542e 100644 --- a/tests/ui/hygiene/unpretty-debug.stdout +++ b/tests/ui/hygiene/unpretty-debug.stdout @@ -5,10 +5,16 @@ //@ normalize-stdout: "\d+#" -> "0#" // minimal junk -#![feature /* 0#0 */(no_core)] +#![feature /* 0#0 */(no_core /* 0#0 */)] #![no_core /* 0#0 */] -macro_rules! foo /* 0#0 */ { ($x: ident) => { y + $x } } +macro_rules! foo + /* + 0#0 + */ { + ($x /* 0#0 */: ident /* 0#0 */) => + { y /* 0#0 */ + $x /* 0#0 */ } +} fn bar /* 0#0 */() { let x /* 0#0 */ = 1; diff --git a/tests/ui/inference/cannot-infer-iterator-sum-return-type.fixed b/tests/ui/inference/cannot-infer-iterator-sum-return-type.fixed new file mode 100644 index 0000000000000..9a494391f0e4f --- /dev/null +++ b/tests/ui/inference/cannot-infer-iterator-sum-return-type.fixed @@ -0,0 +1,13 @@ +//@ run-rustfix +fn main() { + let v = vec![1, 2]; + let sum: i32 = v //~ ERROR: type annotations needed + .iter() + .map(|val| *val) + .sum(); // `sum::` needs `T` to be specified + // In this case any integer would fit, but we resolve to `i32` because that's what `{integer}` + // got coerced to. If the user needs further hinting that they can change the integer type, that + // can come from other suggestions. (#100802) + let bool = sum > 0; + assert_eq!(bool, true); +} diff --git a/tests/ui/inference/cannot-infer-iterator-sum-return-type.rs b/tests/ui/inference/cannot-infer-iterator-sum-return-type.rs new file mode 100644 index 0000000000000..013a2f9148586 --- /dev/null +++ b/tests/ui/inference/cannot-infer-iterator-sum-return-type.rs @@ -0,0 +1,13 @@ +//@ run-rustfix +fn main() { + let v = vec![1, 2]; + let sum = v //~ ERROR: type annotations needed + .iter() + .map(|val| *val) + .sum(); // `sum::` needs `T` to be specified + // In this case any integer would fit, but we resolve to `i32` because that's what `{integer}` + // got coerced to. If the user needs further hinting that they can change the integer type, that + // can come from other suggestions. (#100802) + let bool = sum > 0; + assert_eq!(bool, true); +} diff --git a/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr b/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr new file mode 100644 index 0000000000000..594b6f0181db0 --- /dev/null +++ b/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr @@ -0,0 +1,26 @@ +error[E0283]: type annotations needed + --> $DIR/cannot-infer-iterator-sum-return-type.rs:4:9 + | +LL | let sum = v + | ^^^ +... +LL | .sum(); // `sum::` needs `T` to be specified + | --- type must be known at this point + | + = note: the type must implement `Sum` +help: the trait `Sum` is implemented for `i32` + --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation +note: required by a bound in `std::iter::Iterator::sum` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + = note: this error originates in the macro `integer_sum_product` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider giving `sum` an explicit type, where the type for type parameter `S` is specified + | +LL | let sum: i32 = v + | +++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/kindck/kindck-impl-type-params-2.rs b/tests/ui/kindck/kindck-impl-type-params-2.rs deleted file mode 100644 index 8b0771985dc3f..0000000000000 --- a/tests/ui/kindck/kindck-impl-type-params-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -trait Foo { -} - - - -impl Foo for T { -} - -fn take_param(foo: &T) { } - -fn main() { - let x: Box<_> = Box::new(3); - take_param(&x); - //~^ 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 deleted file mode 100644 index 38dc94f9104d5..0000000000000 --- a/tests/ui/kindck/kindck-impl-type-params-2.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied - --> $DIR/kindck-impl-type-params-2.rs:13:16 - | -LL | take_param(&x); - | ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>` - | | - | required by a bound introduced by this call - | -note: required for `Box<{integer}>` to implement `Foo` - --> $DIR/kindck-impl-type-params-2.rs:6:14 - | -LL | impl Foo for T { - | ---- ^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required by a bound in `take_param` - --> $DIR/kindck-impl-type-params-2.rs:9:17 - | -LL | fn take_param(foo: &T) { } - | ^^^ required by this bound in `take_param` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr deleted file mode 100644 index 95048c4454b31..0000000000000 --- a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ /dev/null @@ -1,56 +0,0 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied - --> $DIR/kindck-inherited-copy-bound.rs:21:16 - | -LL | take_param(&x); - | ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>` - | | - | required by a bound introduced by this call - | -note: required for `Box<{integer}>` to implement `Foo` - --> $DIR/kindck-inherited-copy-bound.rs:14:14 - | -LL | impl Foo for T { - | ---- ^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required by a bound in `take_param` - --> $DIR/kindck-inherited-copy-bound.rs:17:17 - | -LL | fn take_param(foo: &T) { } - | ^^^ required by this bound in `take_param` - -error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/kindck-inherited-copy-bound.rs:28:19 - | -LL | let z = &x as &dyn Foo; - | ^^^^^^^^ `Foo` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/kindck-inherited-copy-bound.rs:10:13 - | -LL | trait Foo : Copy { - | --- ^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - -error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/kindck-inherited-copy-bound.rs:28:13 - | -LL | let z = &x as &dyn Foo; - | ^^ `Foo` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/kindck-inherited-copy-bound.rs:10:13 - | -LL | trait Foo : Copy { - | --- ^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = note: required for the cast from `&Box<{integer}>` to `&dyn Foo` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0038, E0277. -For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/kindck/kindck-nonsendable-1.stderr b/tests/ui/kindck/kindck-nonsendable-1.stderr deleted file mode 100644 index 8bb784d1d4966..0000000000000 --- a/tests/ui/kindck/kindck-nonsendable-1.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/kindck-nonsendable-1.rs:9:9 - | -LL | bar(move|| foo(x)); - | --- ------^^^^^^^ - | | | - | | `Rc` cannot be sent between threads safely - | | within this `{closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15}` - | required by a bound introduced by this call - | - = help: within `{closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15}`, the trait `Send` is not implemented for `Rc` -note: required because it's used within this closure - --> $DIR/kindck-nonsendable-1.rs:9:9 - | -LL | bar(move|| foo(x)); - | ^^^^^^ -note: required by a bound in `bar` - --> $DIR/kindck-nonsendable-1.rs:5:21 - | -LL | fn bar(_: F) { } - | ^^^^ required by this bound in `bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-send-object.rs b/tests/ui/kindck/kindck-send-object.rs deleted file mode 100644 index f5d44246efe5a..0000000000000 --- a/tests/ui/kindck/kindck-send-object.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test which of the builtin types are considered sendable. The tests -// in this file all test the "kind" violates detected during kindck. -// See all `regions-bounded-by-send.rs` - -fn assert_send() { } -trait Dummy { } -trait Message : Send { } - -// careful with object types, who knows what they close over... - -fn object_ref_with_static_bound_not_ok() { - assert_send::<&'static (dyn Dummy + 'static)>(); - //~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277] -} - -fn box_object_with_no_bound_not_ok<'a>() { - assert_send::>(); - //~^ ERROR `dyn Dummy` cannot be sent between threads safely -} - -fn object_with_send_bound_ok() { - assert_send::<&'static (dyn Dummy + Sync)>(); - assert_send::>(); -} - -fn main() { } diff --git a/tests/ui/kindck/kindck-send-object.stderr b/tests/ui/kindck/kindck-send-object.stderr deleted file mode 100644 index b71d4029350e1..0000000000000 --- a/tests/ui/kindck/kindck-send-object.stderr +++ /dev/null @@ -1,33 +0,0 @@ -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)>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely - | - = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` - = 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 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error[E0277]: `dyn Dummy` cannot be sent between threads safely - --> $DIR/kindck-send-object.rs:17:19 - | -LL | assert_send::>(); - | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `dyn Dummy` - = note: required for `std::ptr::Unique` to implement `Send` -note: required because it appears within the type `Box` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL -note: required by a bound in `assert_send` - --> $DIR/kindck-send-object.rs:5:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-send-object1.rs b/tests/ui/kindck/kindck-send-object1.rs deleted file mode 100644 index 76a9fc6019abc..0000000000000 --- a/tests/ui/kindck/kindck-send-object1.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Test which object types are considered sendable. This test -// is broken into two parts because some errors occur in distinct -// phases in the compiler. See kindck-send-object2.rs as well! - -fn assert_send() { } -trait Dummy { } - -// careful with object types, who knows what they close over... -fn test51<'a>() { - assert_send::<&'a dyn Dummy>(); - //~^ ERROR `&'a (dyn Dummy + 'a)` cannot be sent between threads safely [E0277] -} -fn test52<'a>() { - assert_send::<&'a (dyn Dummy + Sync)>(); - //~^ ERROR: lifetime may not live long enough -} - -// ...unless they are properly bounded -fn test60() { - assert_send::<&'static (dyn Dummy + Sync)>(); -} -fn test61() { - assert_send::>(); -} - -// closure and object types can have lifetime bounds which make -// them not ok -fn test_71<'a>() { - assert_send::>(); - //~^ ERROR `(dyn Dummy + 'a)` cannot be sent between threads safely -} - -fn main() { } diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr deleted file mode 100644 index 2184ae704673d..0000000000000 --- a/tests/ui/kindck/kindck-send-object1.stderr +++ /dev/null @@ -1,41 +0,0 @@ -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>(); - | ^^^^^^^^^^^^^ `&'a (dyn Dummy + 'a)` cannot be sent between threads safely - | - = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)` - = 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 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely - --> $DIR/kindck-send-object1.rs:29:19 - | -LL | assert_send::>(); - | ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` - = note: required for `std::ptr::Unique<(dyn Dummy + 'a)>` to implement `Send` -note: required because it appears within the type `Box<(dyn Dummy + 'a)>` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL -note: required by a bound in `assert_send` - --> $DIR/kindck-send-object1.rs:5:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error: lifetime may not live long enough - --> $DIR/kindck-send-object1.rs:14:5 - | -LL | fn test52<'a>() { - | -- lifetime `'a` defined here -LL | assert_send::<&'a (dyn Dummy + Sync)>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-send-object2.rs b/tests/ui/kindck/kindck-send-object2.rs deleted file mode 100644 index d37074e657462..0000000000000 --- a/tests/ui/kindck/kindck-send-object2.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Continue kindck-send-object1.rs. - -fn assert_send() { } -trait Dummy { } - -fn test50() { - assert_send::<&'static dyn Dummy>(); - //~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277] -} - -fn test53() { - assert_send::>(); - //~^ ERROR `dyn Dummy` cannot be sent between threads safely -} - -// ...unless they are properly bounded -fn test60() { - assert_send::<&'static (dyn Dummy + Sync)>(); -} -fn test61() { - assert_send::>(); -} - -fn main() { } diff --git a/tests/ui/kindck/kindck-send-object2.stderr b/tests/ui/kindck/kindck-send-object2.stderr deleted file mode 100644 index 52a7055b42291..0000000000000 --- a/tests/ui/kindck/kindck-send-object2.stderr +++ /dev/null @@ -1,33 +0,0 @@ -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>(); - | ^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely - | - = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` - = 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 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error[E0277]: `dyn Dummy` cannot be sent between threads safely - --> $DIR/kindck-send-object2.rs:12:19 - | -LL | assert_send::>(); - | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `dyn Dummy` - = note: required for `std::ptr::Unique` to implement `Send` -note: required because it appears within the type `Box` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL -note: required by a bound in `assert_send` - --> $DIR/kindck-send-object2.rs:3:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-send-owned.rs b/tests/ui/kindck/kindck-send-owned.rs deleted file mode 100644 index 65efb69041d59..0000000000000 --- a/tests/ui/kindck/kindck-send-owned.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Test which of the builtin types are considered sendable. - -fn assert_send() { } - -// owned content are ok -fn test30() { assert_send::>(); } -fn test31() { assert_send::(); } -fn test32() { assert_send:: >(); } - -// but not if they own a bad thing -fn test40() { - assert_send::>(); - //~^ ERROR `*mut u8` cannot be sent between threads safely -} - -fn main() { } diff --git a/tests/ui/kindck/kindck-send-owned.stderr b/tests/ui/kindck/kindck-send-owned.stderr deleted file mode 100644 index c433d80cf140c..0000000000000 --- a/tests/ui/kindck/kindck-send-owned.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0277]: `*mut u8` cannot be sent between threads safely - --> $DIR/kindck-send-owned.rs:12:19 - | -LL | assert_send::>(); - | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `*mut u8` - = note: required for `std::ptr::Unique<*mut u8>` to implement `Send` -note: required because it appears within the type `Box<*mut u8>` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL -note: required by a bound in `assert_send` - --> $DIR/kindck-send-owned.rs:3:18 - | -LL | fn assert_send() { } - | ^^^^ required by this bound in `assert_send` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-send-unsafe.rs b/tests/ui/kindck/kindck-send-unsafe.rs deleted file mode 100644 index eb1f2a549b16b..0000000000000 --- a/tests/ui/kindck/kindck-send-unsafe.rs +++ /dev/null @@ -1,15 +0,0 @@ -extern crate core; - -fn assert_send() {} - -fn test70() { - assert_send::<*mut isize>(); - //~^ ERROR `*mut isize` cannot be sent between threads safely -} - -fn test71<'a>() { - assert_send::<*mut &'a isize>(); - //~^ ERROR `*mut &'a isize` cannot be sent between threads safely -} - -fn main() {} diff --git a/tests/ui/kindck/kindck-send-unsafe.stderr b/tests/ui/kindck/kindck-send-unsafe.stderr deleted file mode 100644 index f1a5054abbc47..0000000000000 --- a/tests/ui/kindck/kindck-send-unsafe.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0277]: `*mut isize` cannot be sent between threads safely - --> $DIR/kindck-send-unsafe.rs:6:19 - | -LL | assert_send::<*mut isize>(); - | ^^^^^^^^^^ `*mut isize` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `*mut isize` -note: required by a bound in `assert_send` - --> $DIR/kindck-send-unsafe.rs:3:19 - | -LL | fn assert_send() {} - | ^^^^ required by this bound in `assert_send` - -error[E0277]: `*mut &'a isize` cannot be sent between threads safely - --> $DIR/kindck-send-unsafe.rs:11:19 - | -LL | assert_send::<*mut &'a isize>(); - | ^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `*mut &'a isize` -note: required by a bound in `assert_send` - --> $DIR/kindck-send-unsafe.rs:3:19 - | -LL | fn assert_send() {} - | ^^^^ required by this bound in `assert_send` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/lint/for-loops-over-fallibles/auxiliary/external-macro-issue-148114.rs b/tests/ui/lint/for-loops-over-fallibles/auxiliary/external-macro-issue-148114.rs new file mode 100644 index 0000000000000..68eff33cb3f10 --- /dev/null +++ b/tests/ui/lint/for-loops-over-fallibles/auxiliary/external-macro-issue-148114.rs @@ -0,0 +1,13 @@ +#[macro_export] +macro_rules! identity { + ($x:ident) => { + $x + }; +} + +#[macro_export] +macro_rules! do_loop { + ($x:ident) => { + for $crate::identity!($x) in $x {} + }; +} diff --git a/tests/ui/lint/for-loops-over-fallibles/external-macro-issue-148114.rs b/tests/ui/lint/for-loops-over-fallibles/external-macro-issue-148114.rs new file mode 100644 index 0000000000000..ca3ac3b9a8647 --- /dev/null +++ b/tests/ui/lint/for-loops-over-fallibles/external-macro-issue-148114.rs @@ -0,0 +1,14 @@ +//@ check-pass +//@ aux-build:external-macro-issue-148114.rs + +// This test ensures we do not trigger the lint on external macros +// ref. + +#![deny(for_loops_over_fallibles)] + +extern crate external_macro_issue_148114 as dep; + +fn main() { + let _name = Some(1); + dep::do_loop!(_name); +} diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs b/tests/ui/lint/for-loops-over-fallibles/macro-issue-140747.rs similarity index 100% rename from tests/ui/lint/for-loops-over-falibles/macro-issue-140747.rs rename to tests/ui/lint/for-loops-over-fallibles/macro-issue-140747.rs diff --git a/tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr b/tests/ui/lint/for-loops-over-fallibles/macro-issue-140747.stderr similarity index 100% rename from tests/ui/lint/for-loops-over-falibles/macro-issue-140747.stderr rename to tests/ui/lint/for-loops-over-fallibles/macro-issue-140747.stderr diff --git a/tests/ui/lint/for-loops-over-fallibles/macro-iterator-next.rs b/tests/ui/lint/for-loops-over-fallibles/macro-iterator-next.rs new file mode 100644 index 0000000000000..0fe88734099c7 --- /dev/null +++ b/tests/ui/lint/for-loops-over-fallibles/macro-iterator-next.rs @@ -0,0 +1,21 @@ +// This test ensures that the `for-loops-over-fallibles` lint doesn't suggest +// removing `next`. +// ref. + +#![forbid(for_loops_over_fallibles)] +//~^ NOTE: the lint level is defined here + +fn main() { + macro_rules! mac { + (next $e:expr) => { + $e.iter().next() + }; + } + + for _ in mac!(next [1, 2]) {} + //~^ ERROR: for loop over an `Option`. This is more readably written as an `if let` statement + //~| NOTE: in this expansion of desugaring of `for` loop + //~| NOTE: in this expansion of desugaring of `for` loop + //~| HELP: to check pattern in a loop use `while let` + //~| HELP: consider using `if let` to clear intent +} diff --git a/tests/ui/lint/for-loops-over-fallibles/macro-iterator-next.stderr b/tests/ui/lint/for-loops-over-fallibles/macro-iterator-next.stderr new file mode 100644 index 0000000000000..36848fffa4394 --- /dev/null +++ b/tests/ui/lint/for-loops-over-fallibles/macro-iterator-next.stderr @@ -0,0 +1,24 @@ +error: for loop over an `Option`. This is more readably written as an `if let` statement + --> $DIR/macro-iterator-next.rs:15:14 + | +LL | for _ in mac!(next [1, 2]) {} + | ^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/macro-iterator-next.rs:5:11 + | +LL | #![forbid(for_loops_over_fallibles)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: to check pattern in a loop use `while let` + | +LL - for _ in mac!(next [1, 2]) {} +LL + while let Some(_) = mac!(next [1, 2]) {} + | +help: consider using `if let` to clear intent + | +LL - for _ in mac!(next [1, 2]) {} +LL + if let Some(_) = mac!(next [1, 2]) {} + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/mismatched_types/expectation-from-return-type.rs b/tests/ui/mismatched_types/expectation-from-return-type.rs new file mode 100644 index 0000000000000..ffe3d929984df --- /dev/null +++ b/tests/ui/mismatched_types/expectation-from-return-type.rs @@ -0,0 +1,21 @@ +use std::ptr; + +fn main() { //~ NOTE: this implicit `()` return type influences the call expression's return type + let a = 0; + ptr::read(&a) + //~^ ERROR: mismatched types + //~| NOTE: expected `*const ()`, found `&{integer}` + //~| NOTE: arguments to this function are incorrect + //~| NOTE: expected raw pointer + //~| NOTE: function defined here +} + +fn foo() { //~ NOTE: this implicit `()` return type influences the call expression's return type + let a = 0; + return ptr::read(&a); + //~^ ERROR: mismatched types + //~| NOTE: expected `*const ()`, found `&{integer}` + //~| NOTE: arguments to this function are incorrect + //~| NOTE: expected raw pointer + //~| NOTE: function defined here +} diff --git a/tests/ui/mismatched_types/expectation-from-return-type.stderr b/tests/ui/mismatched_types/expectation-from-return-type.stderr new file mode 100644 index 0000000000000..3bd7a21f987fc --- /dev/null +++ b/tests/ui/mismatched_types/expectation-from-return-type.stderr @@ -0,0 +1,35 @@ +error[E0308]: mismatched types + --> $DIR/expectation-from-return-type.rs:5:15 + | +LL | fn main() { + | - this implicit `()` return type influences the call expression's return type +LL | let a = 0; +LL | ptr::read(&a) + | --------- ^^ expected `*const ()`, found `&{integer}` + | | + | arguments to this function are incorrect + | + = note: expected raw pointer `*const ()` + found reference `&{integer}` +note: function defined here + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + +error[E0308]: mismatched types + --> $DIR/expectation-from-return-type.rs:15:22 + | +LL | fn foo() { + | - this implicit `()` return type influences the call expression's return type +LL | let a = 0; +LL | return ptr::read(&a); + | --------- ^^ expected `*const ()`, found `&{integer}` + | | + | arguments to this function are incorrect + | + = note: expected raw pointer `*const ()` + found reference `&{integer}` +note: function defined here + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/mismatched_types/transforming-option-ref-issue-127545.stderr b/tests/ui/mismatched_types/transforming-option-ref-issue-127545.stderr index 9a18798db2139..6243a9a729a2f 100644 --- a/tests/ui/mismatched_types/transforming-option-ref-issue-127545.stderr +++ b/tests/ui/mismatched_types/transforming-option-ref-issue-127545.stderr @@ -16,6 +16,8 @@ LL | arg.map(|v| &**v) error[E0308]: mismatched types --> $DIR/transforming-option-ref-issue-127545.rs:9:19 | +LL | pub fn bar(arg: Option<&Vec>) -> &[i32] { + | ------ this return type influences the call expression's return type LL | arg.unwrap_or(&[]) | --------- ^^^ expected `&Vec`, found `&[_; 0]` | | @@ -41,6 +43,8 @@ LL + arg.map_or(&[], |v| v) error[E0308]: mismatched types --> $DIR/transforming-option-ref-issue-127545.rs:13:19 | +LL | pub fn barzz<'a>(arg: Option<&'a Vec>, v: &'a [i32]) -> &'a [i32] { + | --------- this return type influences the call expression's return type LL | arg.unwrap_or(v) | --------- ^ expected `&Vec`, found `&[i32]` | | @@ -66,6 +70,8 @@ LL + arg.map_or(v, |v| v) error[E0308]: mismatched types --> $DIR/transforming-option-ref-issue-127545.rs:17:19 | +LL | pub fn convert_result(arg: Result<&Vec, ()>) -> &[i32] { + | ------ this return type influences the call expression's return type LL | arg.unwrap_or(&[]) | --------- ^^^ expected `&Vec`, found `&[_; 0]` | | diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index b5db9922b31a8..a03e567bd48aa 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -1,7 +1,7 @@ Def site: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:26:37: 26:43 (#3) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:26:43: 26:44 (#3) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:26:44: 26:45 (#3) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:26:45: 26:50 (#3) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:26:50: 26:51 (#3) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:26:51: 26:53 (#3) }] Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Ident { ident: "dummy", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }] -#![feature /* 0#0 */(prelude_import)] +#![feature /* 0#0 */(prelude_import /* 0#0 */)] //@ aux-build:make-macro.rs //@ proc-macro: meta-macro.rs //@ edition:2018 @@ -30,7 +30,8 @@ macro_rules! produce_it */ { () => { - meta_macro::print_def_site!($crate::dummy!()); + meta_macro /* 0#0 */::print_def_site /* 0#0 + */!($crate /* 0#0 */::dummy /* 0#0 */!()); // `print_def_site!` will respan the `$crate` identifier // with `Span::def_site()`. This should cause it to resolve // relative to `meta_macro`, *not* `make_macro` (despite diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index e45abab03b4c4..61b55782e6e9d 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -20,7 +20,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ span: $DIR/nonterminal-token-hygiene.rs:23:27: 23:32 (#4), }, ] -#![feature /* 0#0 */(prelude_import)] +#![feature /* 0#0 */(prelude_import /* 0#0 */)] #![no_std /* 0#0 */] // Make sure that marks from declarative macros are applied to tokens in nonterminal. @@ -34,7 +34,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ //@ proc-macro: test-macros.rs //@ edition: 2015 -#![feature /* 0#0 */(decl_macro)] +#![feature /* 0#0 */(decl_macro /* 0#0 */)] #![no_std /* 0#0 */] extern crate core /* 0#2 */; #[prelude_import /* 0#1 */] @@ -49,15 +49,22 @@ macro_rules! outer /* 0#0 */ { - ($item:item) => + ($item /* 0#0 */:item /* 0#0 */) => { - macro inner() { print_bang! { $item } } inner!(); + macro /* 0#0 */ inner /* 0#0 */() + { print_bang /* 0#0 */! { $item /* 0#0 */ } } inner /* 0#0 + */!(); }; } struct S /* 0#0 */; -macro inner /* 0#3 */ { () => { print_bang! { struct S; } } } +macro inner + /* + 0#3 + */ { + () => { print_bang /* 0#3 */! { struct /* 0#0 */ S /* 0#0 */; } } +} struct S /* 0#5 */; // OK, not a duplicate definition of `S` diff --git a/tests/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs b/tests/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs deleted file mode 100644 index 3d4a305078843..0000000000000 --- a/tests/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its -// arguments (like `'a`) outlive `'b`. -// -// Rule OutlivesNominalType from RFC 1214. - -//@ check-pass - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -mod rev_variant_struct_region { - struct Foo<'a> { - x: fn(&'a i32), - } - enum Bar<'a,'b> { - V(&'a Foo<'b>) - } -} - -fn main() { } diff --git a/tests/ui/regions/regions-outlives-nominal-type-enum-region.rs b/tests/ui/regions/regions-outlives-nominal-type-enum-region.rs deleted file mode 100644 index 2e0d1b36ca59e..0000000000000 --- a/tests/ui/regions/regions-outlives-nominal-type-enum-region.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its -// arguments (like `'a`) outlive `'b`. -// -// Rule OutlivesNominalType from RFC 1214. - -//@ check-pass - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -mod variant_struct_region { - struct Foo<'a> { - x: &'a i32, - } - enum Bar<'a,'b> { - V(&'a Foo<'b>) - } -} - -fn main() { } diff --git a/tests/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs b/tests/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs deleted file mode 100644 index baf7874bc1a61..0000000000000 --- a/tests/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its -// arguments (like `'a`) outlive `'b`. -// -// Rule OutlivesNominalType from RFC 1214. - -//@ check-pass - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -mod variant_struct_type { - struct Foo { - x: fn(T) - } - enum Bar<'a,'b> { - V(&'a Foo<&'b i32>) - } -} - -fn main() { } diff --git a/tests/ui/regions/regions-outlives-nominal-type-enum-type.rs b/tests/ui/regions/regions-outlives-nominal-type-enum-type.rs deleted file mode 100644 index b8392c967b10a..0000000000000 --- a/tests/ui/regions/regions-outlives-nominal-type-enum-type.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its -// arguments (like `'a`) outlive `'b`. -// -// Rule OutlivesNominalType from RFC 1214. - -//@ check-pass - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -mod variant_struct_type { - struct Foo { - x: T - } - enum Bar<'a,'b> { - V(&'a Foo<&'b i32>) - } -} - -fn main() { } diff --git a/tests/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs b/tests/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs deleted file mode 100644 index 6a50248cb70b0..0000000000000 --- a/tests/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its -// arguments (like `'a`) outlive `'b`. -// -// Rule OutlivesNominalType from RFC 1214. - -//@ check-pass - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -mod rev_variant_struct_region { - struct Foo<'a> { - x: fn(&'a i32), - } - struct Bar<'a,'b> { - f: &'a Foo<'b> - } -} - -fn main() { } diff --git a/tests/ui/regions/regions-outlives-nominal-type-struct-region.rs b/tests/ui/regions/regions-outlives-nominal-type-struct-region.rs deleted file mode 100644 index 17564bcbf269f..0000000000000 --- a/tests/ui/regions/regions-outlives-nominal-type-struct-region.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its -// arguments (like `'a`) outlive `'b`. -// -// Rule OutlivesNominalType from RFC 1214. - -//@ check-pass - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -mod variant_struct_region { - struct Foo<'a> { - x: &'a i32, - } - struct Bar<'a,'b> { - f: &'a Foo<'b> - } -} - -fn main() { } diff --git a/tests/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs b/tests/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs deleted file mode 100644 index 33961de7d6a45..0000000000000 --- a/tests/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its -// arguments (like `'a`) outlive `'b`. -// -// Rule OutlivesNominalType from RFC 1214. - -//@ check-pass - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -mod rev_variant_struct_type { - struct Foo { - x: fn(T) - } - struct Bar<'a,'b> { - f: &'a Foo<&'b i32> - } -} - -fn main() { } diff --git a/tests/ui/regions/regions-outlives-nominal-type-struct-type.rs b/tests/ui/regions/regions-outlives-nominal-type-struct-type.rs deleted file mode 100644 index c5238086fc05d..0000000000000 --- a/tests/ui/regions/regions-outlives-nominal-type-struct-type.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its -// arguments (like `'a`) outlive `'b`. -// -// Rule OutlivesNominalType from RFC 1214. - -//@ check-pass - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -mod variant_struct_type { - struct Foo { - x: T - } - struct Bar<'a,'b> { - f: &'a Foo<&'b i32> - } -} - -fn main() { } diff --git a/tests/ui/regions/regions-outlives-nominal-type.rs b/tests/ui/regions/regions-outlives-nominal-type.rs new file mode 100644 index 0000000000000..177d064042dd8 --- /dev/null +++ b/tests/ui/regions/regions-outlives-nominal-type.rs @@ -0,0 +1,80 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + +//@ check-pass + +mod variant_enum_region { + struct Foo<'a> { + x: &'a i32, + } + enum Bar<'a, 'b> { + V(&'a Foo<'b>), + } +} + +mod rev_variant_enum_region { + struct Foo<'a> { + x: fn(&'a i32), + } + enum Bar<'a, 'b> { + V(&'a Foo<'b>), + } +} + +mod variant_enum_type { + struct Foo { + x: T, + } + enum Bar<'a, 'b> { + V(&'a Foo<&'b i32>), + } +} + +mod rev_variant_enum_type { + struct Foo { + x: fn(T), + } + enum Bar<'a, 'b> { + V(&'a Foo<&'b i32>), + } +} + +mod variant_struct_region { + struct Foo<'a> { + x: &'a i32, + } + struct Bar<'a, 'b> { + f: &'a Foo<'b>, + } +} + +mod rev_variant_struct_region { + struct Foo<'a> { + x: fn(&'a i32), + } + struct Bar<'a, 'b> { + f: &'a Foo<'b>, + } +} + +mod variant_struct_type { + struct Foo { + x: T, + } + struct Bar<'a, 'b> { + f: &'a Foo<&'b i32>, + } +} + +mod rev_variant_struct_type { + struct Foo { + x: fn(T), + } + struct Bar<'a, 'b> { + f: &'a Foo<&'b i32>, + } +} + +fn main() {} diff --git a/tests/ui/kindck/kindck-copy.rs b/tests/ui/traits/basic-copyable-types.rs similarity index 63% rename from tests/ui/kindck/kindck-copy.rs rename to tests/ui/traits/basic-copyable-types.rs index 36bf0d2b785f6..c953b60260df4 100644 --- a/tests/ui/kindck/kindck-copy.rs +++ b/tests/ui/traits/basic-copyable-types.rs @@ -2,9 +2,9 @@ use std::rc::Rc; -fn assert_copy() { } +fn assert_copy() {} -trait Dummy { } +trait Dummy {} #[derive(Copy, Clone)] struct MyStruct { @@ -16,8 +16,8 @@ struct MyNoncopyStruct { x: Box, } -fn test<'a,T,U:Copy>(_: &'a isize) { - // lifetime pointers are ok... +fn test<'a, T, U: Copy>(_: &'a isize) { + // references are ok... assert_copy::<&'static isize>(); assert_copy::<&'a isize>(); assert_copy::<&'a str>(); @@ -25,25 +25,25 @@ fn test<'a,T,U:Copy>(_: &'a isize) { // ...unless they are mutable assert_copy::<&'static mut isize>(); //~ ERROR : Copy` is not satisfied - assert_copy::<&'a mut isize>(); //~ ERROR : Copy` is not satisfied + assert_copy::<&'a mut isize>(); //~ ERROR : Copy` is not satisfied // boxes are not ok - assert_copy::>(); //~ ERROR : Copy` is not satisfied - assert_copy::(); //~ ERROR : Copy` is not satisfied - assert_copy:: >(); //~ ERROR : Copy` is not satisfied + assert_copy::>(); //~ ERROR : Copy` is not satisfied + assert_copy::(); //~ ERROR : Copy` is not satisfied + assert_copy::>(); //~ ERROR : Copy` is not satisfied assert_copy::>(); //~ ERROR : Copy` is not satisfied - // borrowed object types are generally ok + // borrowed trait objects are generally ok assert_copy::<&'a dyn Dummy>(); assert_copy::<&'a (dyn Dummy + Send)>(); assert_copy::<&'static (dyn Dummy + Send)>(); - // owned object types are not ok + // boxed trait objects are not ok assert_copy::>(); //~ ERROR : Copy` is not satisfied assert_copy::>(); //~ ERROR : Copy` is not satisfied - // mutable object types are not ok - assert_copy::<&'a mut (dyn Dummy + Send)>(); //~ ERROR : Copy` is not satisfied + // mutable references to trait objects are not ok + assert_copy::<&'a mut (dyn Dummy + Send)>(); //~ ERROR : Copy` is not satisfied // raw ptrs are ok assert_copy::<*const isize>(); @@ -55,7 +55,7 @@ fn test<'a,T,U:Copy>(_: &'a isize) { assert_copy::<()>(); // tuples are ok - assert_copy::<(isize,isize)>(); + assert_copy::<(isize, isize)>(); // structs of POD are ok assert_copy::(); @@ -64,8 +64,7 @@ fn test<'a,T,U:Copy>(_: &'a isize) { assert_copy::(); //~ ERROR : Copy` is not satisfied // ref counted types are not ok - assert_copy::>(); //~ ERROR : Copy` is not satisfied + assert_copy::>(); //~ ERROR : Copy` is not satisfied } -pub fn main() { -} +pub fn main() {} diff --git a/tests/ui/kindck/kindck-copy.stderr b/tests/ui/traits/basic-copyable-types.stderr similarity index 61% rename from tests/ui/kindck/kindck-copy.stderr rename to tests/ui/traits/basic-copyable-types.stderr index f5623ddd4f795..b4fa957533357 100644 --- a/tests/ui/kindck/kindck-copy.stderr +++ b/tests/ui/traits/basic-copyable-types.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `&'static mut isize: Copy` is not satisfied - --> $DIR/kindck-copy.rs:27:19 + --> $DIR/basic-copyable-types.rs:27:19 | LL | assert_copy::<&'static mut isize>(); | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'static mut isize` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` help: consider removing the leading `&`-reference | LL - assert_copy::<&'static mut isize>(); @@ -16,16 +16,16 @@ LL + assert_copy::(); | error[E0277]: the trait bound `&'a mut isize: Copy` is not satisfied - --> $DIR/kindck-copy.rs:28:19 + --> $DIR/basic-copyable-types.rs:28:19 | LL | assert_copy::<&'a mut isize>(); | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'a mut isize` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` help: consider removing the leading `&`-reference | LL - assert_copy::<&'a mut isize>(); @@ -33,117 +33,117 @@ LL + assert_copy::(); | error[E0277]: the trait bound `Box: Copy` is not satisfied - --> $DIR/kindck-copy.rs:31:19 + --> $DIR/basic-copyable-types.rs:31:19 | LL | assert_copy::>(); | ^^^^^^^^^^ the trait `Copy` is not implemented for `Box` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/kindck-copy.rs:32:19 + --> $DIR/basic-copyable-types.rs:32:19 | LL | assert_copy::(); | ^^^^^^ the trait `Copy` is not implemented for `String` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Vec: Copy` is not satisfied - --> $DIR/kindck-copy.rs:33:19 + --> $DIR/basic-copyable-types.rs:33:19 | -LL | assert_copy:: >(); +LL | assert_copy::>(); | ^^^^^^^^^^ the trait `Copy` is not implemented for `Vec` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Box<&'a mut isize>: Copy` is not satisfied - --> $DIR/kindck-copy.rs:34:19 + --> $DIR/basic-copyable-types.rs:34:19 | LL | assert_copy::>(); | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Box<&'a mut isize>` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Box: Copy` is not satisfied - --> $DIR/kindck-copy.rs:42:19 + --> $DIR/basic-copyable-types.rs:42:19 | LL | assert_copy::>(); | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Box` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Box: Copy` is not satisfied - --> $DIR/kindck-copy.rs:43:19 + --> $DIR/basic-copyable-types.rs:43:19 | LL | assert_copy::>(); | ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Box` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `&'a mut (dyn Dummy + Send + 'a): Copy` is not satisfied - --> $DIR/kindck-copy.rs:46:19 + --> $DIR/basic-copyable-types.rs:46:19 | LL | assert_copy::<&'a mut (dyn Dummy + Send)>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'a mut (dyn Dummy + Send + 'a)` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `MyNoncopyStruct: Copy` is not satisfied - --> $DIR/kindck-copy.rs:64:19 + --> $DIR/basic-copyable-types.rs:64:19 | LL | assert_copy::(); | ^^^^^^^^^^^^^^^ unsatisfied trait bound | help: the trait `Copy` is not implemented for `MyNoncopyStruct` - --> $DIR/kindck-copy.rs:15:1 + --> $DIR/basic-copyable-types.rs:15:1 | LL | struct MyNoncopyStruct { | ^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error[E0277]: the trait bound `Rc: Copy` is not satisfied - --> $DIR/kindck-copy.rs:67:19 + --> $DIR/basic-copyable-types.rs:67:19 | LL | assert_copy::>(); | ^^^^^^^^^ the trait `Copy` is not implemented for `Rc` | note: required by a bound in `assert_copy` - --> $DIR/kindck-copy.rs:5:18 + --> $DIR/basic-copyable-types.rs:5:19 | -LL | fn assert_copy() { } - | ^^^^ required by this bound in `assert_copy` +LL | fn assert_copy() {} + | ^^^^ required by this bound in `assert_copy` error: aborting due to 11 previous errors diff --git a/tests/ui/kindck/kindck-nonsendable-1.rs b/tests/ui/traits/closure-rc-not-send.rs similarity index 70% rename from tests/ui/kindck/kindck-nonsendable-1.rs rename to tests/ui/traits/closure-rc-not-send.rs index b32fd78624b8e..78ef834afabdb 100644 --- a/tests/ui/kindck/kindck-nonsendable-1.rs +++ b/tests/ui/traits/closure-rc-not-send.rs @@ -2,10 +2,10 @@ use std::rc::Rc; fn foo(_x: Rc) {} -fn bar(_: F) { } +fn bar(_: F) {} fn main() { let x = Rc::new(3); - bar(move|| foo(x)); + bar(move || foo(x)); //~^ ERROR `Rc` cannot be sent between threads safely } diff --git a/tests/ui/traits/closure-rc-not-send.stderr b/tests/ui/traits/closure-rc-not-send.stderr new file mode 100644 index 0000000000000..5e73f13648d5c --- /dev/null +++ b/tests/ui/traits/closure-rc-not-send.stderr @@ -0,0 +1,25 @@ +error[E0277]: `Rc` cannot be sent between threads safely + --> $DIR/closure-rc-not-send.rs:9:9 + | +LL | bar(move || foo(x)); + | --- -------^^^^^^^ + | | | + | | `Rc` cannot be sent between threads safely + | | within this `{closure@$DIR/closure-rc-not-send.rs:9:9: 9:16}` + | required by a bound introduced by this call + | + = help: within `{closure@$DIR/closure-rc-not-send.rs:9:9: 9:16}`, the trait `Send` is not implemented for `Rc` +note: required because it's used within this closure + --> $DIR/closure-rc-not-send.rs:9:9 + | +LL | bar(move || foo(x)); + | ^^^^^^^ +note: required by a bound in `bar` + --> $DIR/closure-rc-not-send.rs:5:22 + | +LL | fn bar(_: F) {} + | ^^^^ required by this bound in `bar` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/kindck/kindck-impl-type-params.rs b/tests/ui/traits/copy-bounds-impl-type-params.rs similarity index 94% rename from tests/ui/kindck/kindck-impl-type-params.rs rename to tests/ui/traits/copy-bounds-impl-type-params.rs index 707c5dbaec30e..ba54bc313c089 100644 --- a/tests/ui/kindck/kindck-impl-type-params.rs +++ b/tests/ui/traits/copy-bounds-impl-type-params.rs @@ -6,7 +6,9 @@ use std::marker; struct S(marker::PhantomData); trait Gettable { - fn get(&self) -> T { panic!() } + fn get(&self) -> T { + panic!() + } } impl Gettable for S {} @@ -45,4 +47,4 @@ fn foo3<'a>() { //~^ ERROR : Copy` is not satisfied } -fn main() { } +fn main() {} diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/traits/copy-bounds-impl-type-params.stderr similarity index 86% rename from tests/ui/kindck/kindck-impl-type-params.stderr rename to tests/ui/traits/copy-bounds-impl-type-params.stderr index 0c9ab13f4774a..08fde8fb5df35 100644 --- a/tests/ui/kindck/kindck-impl-type-params.stderr +++ b/tests/ui/traits/copy-bounds-impl-type-params.stderr @@ -1,11 +1,11 @@ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/kindck-impl-type-params.rs:16:13 + --> $DIR/copy-bounds-impl-type-params.rs:18:13 | LL | let a = &t as &dyn Gettable; | ^^ `T` cannot be sent between threads safely | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -18,13 +18,13 @@ LL | fn f(val: T) { | +++++++++++++++++++ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:16:13 + --> $DIR/copy-bounds-impl-type-params.rs:18:13 | LL | let a = &t as &dyn Gettable; | ^^ the trait `Copy` is not implemented for `T` | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -37,13 +37,13 @@ LL | fn f(val: T) { | +++++++++++++++++++ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/kindck-impl-type-params.rs:23:31 + --> $DIR/copy-bounds-impl-type-params.rs:25:31 | LL | let a: &dyn Gettable = &t; | ^^ `T` cannot be sent between threads safely | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -56,13 +56,13 @@ LL | fn g(val: T) { | +++++++++++++++++++ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:23:31 + --> $DIR/copy-bounds-impl-type-params.rs:25:31 | LL | let a: &dyn Gettable = &t; | ^^ the trait `Copy` is not implemented for `T` | note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -75,18 +75,18 @@ LL | fn g(val: T) { | +++++++++++++++++++ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:36:13 + --> $DIR/copy-bounds-impl-type-params.rs:38:13 | LL | let a = t as Box>; | ^ the trait `Copy` is not implemented for `String` | help: the trait `Gettable` is implemented for `S` - --> $DIR/kindck-impl-type-params.rs:12:1 + --> $DIR/copy-bounds-impl-type-params.rs:14:1 | LL | impl Gettable for S {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -95,18 +95,18 @@ LL | impl Gettable for S {} = note: required for the cast from `Box>` to `Box>` error[E0277]: the trait bound `Foo: Copy` is not satisfied - --> $DIR/kindck-impl-type-params.rs:44:37 + --> $DIR/copy-bounds-impl-type-params.rs:46:37 | LL | let a: Box> = t; | ^ the trait `Copy` is not implemented for `Foo` | help: the trait `Gettable` is implemented for `S` - --> $DIR/kindck-impl-type-params.rs:12:1 + --> $DIR/copy-bounds-impl-type-params.rs:14:1 | LL | impl Gettable for S {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required for `S` to implement `Gettable` - --> $DIR/kindck-impl-type-params.rs:12:32 + --> $DIR/copy-bounds-impl-type-params.rs:14:32 | LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ @@ -120,7 +120,7 @@ LL | struct Foo; // does not impl Copy | error: lifetime may not live long enough - --> $DIR/kindck-impl-type-params.rs:30:13 + --> $DIR/copy-bounds-impl-type-params.rs:32:13 | LL | fn foo<'a>() { | -- lifetime `'a` defined here diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.rs b/tests/ui/traits/inherited-copy-bound.rs similarity index 75% rename from tests/ui/kindck/kindck-inherited-copy-bound.rs rename to tests/ui/traits/inherited-copy-bound.rs index 92c2b273c2c15..dd9fea3dcde35 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.rs +++ b/tests/ui/traits/inherited-copy-bound.rs @@ -1,16 +1,14 @@ // Test that Copy bounds inherited by trait are checked. - use std::any::Any; -trait Foo : Copy { +trait Foo: Copy { fn foo(&self) {} } -impl Foo for T { -} +impl Foo for T {} -fn take_param(foo: &T) { } +fn take_param(foo: &T) {} fn a() { let x: Box<_> = Box::new(3); @@ -24,4 +22,4 @@ fn b() { //~^ ERROR E0038 } -fn main() { } +fn main() {} diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.stderr b/tests/ui/traits/inherited-copy-bound.stderr similarity index 62% rename from tests/ui/kindck/kindck-inherited-copy-bound.stderr rename to tests/ui/traits/inherited-copy-bound.stderr index c15aabacddd17..c251d59224463 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.stderr +++ b/tests/ui/traits/inherited-copy-bound.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied - --> $DIR/kindck-inherited-copy-bound.rs:17:16 + --> $DIR/inherited-copy-bound.rs:15:16 | LL | take_param(&x); | ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>` @@ -7,30 +7,30 @@ LL | take_param(&x); | required by a bound introduced by this call | note: required for `Box<{integer}>` to implement `Foo` - --> $DIR/kindck-inherited-copy-bound.rs:10:14 + --> $DIR/inherited-copy-bound.rs:9:15 | -LL | impl Foo for T { - | ---- ^^^ ^ - | | - | unsatisfied trait bound introduced here +LL | impl Foo for T {} + | ---- ^^^ ^ + | | + | unsatisfied trait bound introduced here note: required by a bound in `take_param` - --> $DIR/kindck-inherited-copy-bound.rs:13:17 + --> $DIR/inherited-copy-bound.rs:11:18 | -LL | fn take_param(foo: &T) { } - | ^^^ required by this bound in `take_param` +LL | fn take_param(foo: &T) {} + | ^^^ required by this bound in `take_param` error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/kindck-inherited-copy-bound.rs:23:24 + --> $DIR/inherited-copy-bound.rs:21:24 | LL | let z = &x as &dyn Foo; | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/kindck-inherited-copy-bound.rs:6:13 + --> $DIR/inherited-copy-bound.rs:5:12 | -LL | trait Foo : Copy { - | --- ^^^^ ...because it requires `Self: Sized` +LL | trait Foo: Copy { + | --- ^^^^ ...because it requires `Self: Sized` | | | this trait is not dyn compatible... diff --git a/tests/ui/traits/send-trait-objects-basic.rs b/tests/ui/traits/send-trait-objects-basic.rs new file mode 100644 index 0000000000000..c999d4d0f6950 --- /dev/null +++ b/tests/ui/traits/send-trait-objects-basic.rs @@ -0,0 +1,55 @@ +// Test which trait objects and basic types are considered sendable, considering lifetimes. + +fn assert_send_static() {} +fn assert_send() {} + +trait Dummy {} + +fn test1<'a>() { + assert_send_static::<&'a dyn Dummy>(); + //~^ ERROR `&'a (dyn Dummy + 'a)` cannot be sent between threads safely [E0277] +} + +fn test2<'a>() { + assert_send_static::<&'a (dyn Dummy + Sync)>(); + //~^ ERROR: lifetime may not live long enough +} + +fn test3<'a>() { + assert_send_static::>(); + //~^ ERROR `(dyn Dummy + 'a)` cannot be sent between threads safely +} + +fn test4<'a>() { + assert_send::<*mut &'a isize>(); + //~^ ERROR `*mut &'a isize` cannot be sent between threads safely +} + +fn main() { + assert_send_static::<&'static (dyn Dummy + Sync)>(); + assert_send_static::>(); + + assert_send::<&'static dyn Dummy>(); + //~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277] + assert_send::>(); + //~^ ERROR `dyn Dummy` cannot be sent between threads safely + assert_send::<&'static (dyn Dummy + Sync)>(); + assert_send::>(); + + // owned content is ok + assert_send::>(); + assert_send::(); + assert_send::>(); + + // but not if it owns a bad thing + assert_send::>(); + //~^ ERROR `*mut u8` cannot be sent between threads safely + + assert_send::<*mut isize>(); + //~^ ERROR `*mut isize` cannot be sent between threads safely +} + +fn object_ref_with_static_bound_not_ok() { + assert_send::<&'static (dyn Dummy + 'static)>(); + //~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277] +} diff --git a/tests/ui/traits/send-trait-objects-basic.stderr b/tests/ui/traits/send-trait-objects-basic.stderr new file mode 100644 index 0000000000000..0393f7bc19df7 --- /dev/null +++ b/tests/ui/traits/send-trait-objects-basic.stderr @@ -0,0 +1,127 @@ +error[E0277]: `&'a (dyn Dummy + 'a)` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:9:26 + | +LL | assert_send_static::<&'a dyn Dummy>(); + | ^^^^^^^^^^^^^ `&'a (dyn Dummy + 'a)` cannot be sent between threads safely + | + = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)` + = note: required for `&'a (dyn Dummy + 'a)` to implement `Send` +note: required by a bound in `assert_send_static` + --> $DIR/send-trait-objects-basic.rs:3:26 + | +LL | fn assert_send_static() {} + | ^^^^ required by this bound in `assert_send_static` + +error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:19:26 + | +LL | assert_send_static::>(); + | ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` + = note: required for `std::ptr::Unique<(dyn Dummy + 'a)>` to implement `Send` +note: required because it appears within the type `Box<(dyn Dummy + 'a)>` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL +note: required by a bound in `assert_send_static` + --> $DIR/send-trait-objects-basic.rs:3:26 + | +LL | fn assert_send_static() {} + | ^^^^ required by this bound in `assert_send_static` + +error[E0277]: `*mut &'a isize` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:24:19 + | +LL | assert_send::<*mut &'a isize>(); + | ^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `*mut &'a isize` +note: required by a bound in `assert_send` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:32:19 + | +LL | assert_send::<&'static dyn Dummy>(); + | ^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely + | + = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` + = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` +note: required by a bound in `assert_send` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `dyn Dummy` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:34:19 + | +LL | assert_send::>(); + | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `dyn Dummy` + = note: required for `std::ptr::Unique` to implement `Send` +note: required because it appears within the type `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL +note: required by a bound in `assert_send` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `*mut u8` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:45:19 + | +LL | assert_send::>(); + | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `*mut u8` + = note: required for `std::ptr::Unique<*mut u8>` to implement `Send` +note: required because it appears within the type `Box<*mut u8>` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL +note: required by a bound in `assert_send` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `*mut isize` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:48:19 + | +LL | assert_send::<*mut isize>(); + | ^^^^^^^^^^ `*mut isize` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `*mut isize` +note: required by a bound in `assert_send` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely + --> $DIR/send-trait-objects-basic.rs:53:19 + | +LL | assert_send::<&'static (dyn Dummy + 'static)>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely + | + = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` + = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` +note: required by a bound in `assert_send` + --> $DIR/send-trait-objects-basic.rs:4:19 + | +LL | fn assert_send() {} + | ^^^^ required by this bound in `assert_send` + +error: lifetime may not live long enough + --> $DIR/send-trait-objects-basic.rs:14:5 + | +LL | fn test2<'a>() { + | -- lifetime `'a` defined here +LL | assert_send_static::<&'a (dyn Dummy + Sync)>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr b/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr index 53920bc9e02ec..fd07d5b09aeb0 100644 --- a/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr +++ b/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr @@ -112,6 +112,9 @@ LL + let x: u16 = (S {}).method(0u16); error[E0308]: arguments to this function are incorrect --> $DIR/wrong-call-return-type-due-to-generic-arg.rs:27:5 | +LL | fn main() { + | - this implicit `()` return type influences the call expression's return type +... LL | function(0u32, 8u8) | ^^^^^^^^ ---- --- expected `bool`, found `u8` | |