diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 3e2757ac023f6..02cb6f188a718 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -308,7 +308,7 @@ impl TraitBoundModifiers { #[derive(Clone, Encodable, Decodable, Debug)] pub enum GenericBound { - Trait(PolyTraitRef, TraitBoundModifiers), + Trait(PolyTraitRef), Outlives(Lifetime), /// Precise capturing syntax: `impl Sized + use<'a>` Use(ThinVec, Span), @@ -1213,10 +1213,12 @@ impl Expr { pub fn to_bound(&self) -> Option { match &self.kind { - ExprKind::Path(None, path) => Some(GenericBound::Trait( - PolyTraitRef::new(ThinVec::new(), path.clone(), self.span), + ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new( + ThinVec::new(), + path.clone(), TraitBoundModifiers::NONE, - )), + self.span, + ))), _ => None, } } @@ -2972,6 +2974,9 @@ pub struct PolyTraitRef { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: ThinVec, + // Optional constness, asyncness, or polarity. + pub modifiers: TraitBoundModifiers, + /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`. pub trait_ref: TraitRef, @@ -2979,9 +2984,15 @@ pub struct PolyTraitRef { } impl PolyTraitRef { - pub fn new(generic_params: ThinVec, path: Path, span: Span) -> Self { + pub fn new( + generic_params: ThinVec, + path: Path, + modifiers: TraitBoundModifiers, + span: Span, + ) -> Self { PolyTraitRef { bound_generic_params: generic_params, + modifiers, trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID }, span, } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 6bdd69e7101c6..2afbd979c3023 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -913,7 +913,7 @@ fn walk_fn_ret_ty(vis: &mut T, fn_ret_ty: &mut FnRetTy) { fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) { match pb { - GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty), + GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref), GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime), GenericBound::Use(args, span) => { for arg in args { @@ -1034,7 +1034,7 @@ fn walk_trait_ref(vis: &mut T, TraitRef { path, ref_id }: &mut Tr } fn walk_poly_trait_ref(vis: &mut T, p: &mut PolyTraitRef) { - let PolyTraitRef { bound_generic_params, trait_ref, span } = p; + let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span } = p; bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_trait_ref(trait_ref); vis.visit_span(span); diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index fcc1af5ebc232..ae1ca36a3ba93 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -265,7 +265,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> { ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds) => { match bounds.last() { - Some(ast::GenericBound::Trait(bound, _)) => { + Some(ast::GenericBound::Trait(bound)) => { match path_return_type(&bound.trait_ref.path) { Some(trailing_ty) => ty = trailing_ty, None => break None, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index a8f0e41167d05..207ec71065051 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -329,7 +329,7 @@ pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) where V: Visitor<'a>, { - let PolyTraitRef { bound_generic_params, trait_ref, span: _ } = trait_ref; + let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span: _ } = trait_ref; walk_list!(visitor, visit_generic_param, bound_generic_params); visitor.visit_trait_ref(trait_ref) } @@ -721,7 +721,7 @@ impl WalkItemKind for ForeignItemKind { pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result { match bound { - GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ), + GenericBound::Trait(trait_ref) => visitor.visit_poly_trait_ref(trait_ref), GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound), GenericBound::Use(args, _span) => { walk_list!(visitor, visit_precise_capturing_arg, args); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 1273b50dff816..ce744cc56e1ab 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1504,8 +1504,8 @@ impl<'hir> LoweringContext<'_, 'hir> { for bound in &bound_pred.bounds { if !matches!( *bound, - GenericBound::Trait(_, TraitBoundModifiers { - polarity: BoundPolarity::Maybe(_), + GenericBound::Trait(PolyTraitRef { + modifiers: TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. }, .. }) ) { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5738f89128142..00eafeb4d844d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1224,13 +1224,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let bound = this.lower_poly_trait_ref( &PolyTraitRef { bound_generic_params: ThinVec::new(), + modifiers: TraitBoundModifiers::NONE, trait_ref: TraitRef { path: path.clone(), ref_id: t.id }, span: t.span, }, itctx, - TraitBoundModifiers::NONE, ); - let bound = (bound, hir::TraitBoundModifier::None); let bounds = this.arena.alloc_from_iter([bound]); let lifetime_bound = this.elided_dyn_bound(t.span); (bounds, lifetime_bound) @@ -1357,10 +1356,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // We can safely ignore constness here since AST validation // takes care of rejecting invalid modifier combinations and // const trait bounds in trait object types. - GenericBound::Trait(ty, modifiers) => { - let trait_ref = this.lower_poly_trait_ref(ty, itctx, *modifiers); - let polarity = this.lower_trait_bound_modifiers(*modifiers); - Some((trait_ref, polarity)) + GenericBound::Trait(ty) => { + let trait_ref = this.lower_poly_trait_ref(ty, itctx); + Some(trait_ref) } GenericBound::Outlives(lifetime) => { if lifetime_bound.is_none() { @@ -1993,21 +1991,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span_ext: DUMMY_SP, }); - hir::GenericBound::Trait( - hir::PolyTraitRef { - bound_generic_params: &[], - trait_ref: hir::TraitRef { - path: self.make_lang_item_path( - trait_lang_item, - opaque_ty_span, - Some(bound_args), - ), - hir_ref_id: self.next_id(), - }, - span: opaque_ty_span, + hir::GenericBound::Trait(hir::PolyTraitRef { + bound_generic_params: &[], + modifiers: hir::TraitBoundModifier::None, + trait_ref: hir::TraitRef { + path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)), + hir_ref_id: self.next_id(), }, - hir::TraitBoundModifier::None, - ) + span: opaque_ty_span, + }) } #[instrument(level = "trace", skip(self))] @@ -2017,10 +2009,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { itctx: ImplTraitContext, ) -> hir::GenericBound<'hir> { match tpb { - GenericBound::Trait(p, modifiers) => hir::GenericBound::Trait( - self.lower_poly_trait_ref(p, itctx, *modifiers), - self.lower_trait_bound_modifiers(*modifiers), - ), + GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)), GenericBound::Outlives(lifetime) => { hir::GenericBound::Outlives(self.lower_lifetime(lifetime)) } @@ -2224,12 +2213,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, p: &PolyTraitRef, itctx: ImplTraitContext, - modifiers: ast::TraitBoundModifiers, ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); - let trait_ref = self.lower_trait_ref(modifiers, &p.trait_ref, itctx); - hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) } + let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx); + let modifiers = self.lower_trait_bound_modifiers(p.modifiers); + hir::PolyTraitRef { + bound_generic_params, + modifiers, + trait_ref, + span: self.lower_span(p.span), + } } fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> { @@ -2669,10 +2663,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => { let principal = hir::PolyTraitRef { bound_generic_params: &[], + modifiers: hir::TraitBoundModifier::None, trait_ref: hir::TraitRef { path, hir_ref_id: hir_id }, span: self.lower_span(span), }; - let principal = (principal, hir::TraitBoundModifier::None); // The original ID is taken by the `PolyTraitRef`, // so the `Ty` itself needs a different one. diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index a36a9f11c0f15..20a4f2120dcdf 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1263,7 +1263,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if !bound_pred.bound_generic_params.is_empty() { for bound in &bound_pred.bounds { match bound { - GenericBound::Trait(t, _) => { + GenericBound::Trait(t) => { if !t.bound_generic_params.is_empty() { self.dcx() .emit_err(errors::NestedLifetimes { span: t.span }); @@ -1283,8 +1283,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) { match bound { - GenericBound::Trait(trait_ref, modifiers) => { - match (ctxt, modifiers.constness, modifiers.polarity) { + GenericBound::Trait(trait_ref) => { + match (ctxt, trait_ref.modifiers.constness, trait_ref.modifiers.polarity) { (BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_)) if !self.features.more_maybe_bounds => { @@ -1324,7 +1324,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } // Negative trait bounds are not allowed to have associated constraints - if let BoundPolarity::Negative(_) = modifiers.polarity + if let BoundPolarity::Negative(_) = trait_ref.modifiers.polarity && let Some(segment) = trait_ref.trait_ref.path.segments.last() { match segment.args.as_deref() { @@ -1672,7 +1672,9 @@ fn deny_equality_constraints( }), ) { for bound in bounds { - if let GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound { + if let GenericBound::Trait(poly) = bound + && poly.modifiers == TraitBoundModifiers::NONE + { if full_path.segments[..full_path.segments.len() - 1] .iter() .map(|segment| segment.ident.name) @@ -1700,7 +1702,9 @@ fn deny_equality_constraints( ) { if ident == potential_param.ident { for bound in bounds { - if let ast::GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound { + if let ast::GenericBound::Trait(poly) = bound + && poly.modifiers == TraitBoundModifiers::NONE + { suggest(poly, potential_assoc, predicate); } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 39ff237b8355f..2cdec2138ad3b 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -8,7 +8,6 @@ mod item; use std::borrow::Cow; -use ast::TraitBoundModifiers; use rustc_ast::attr::AttrIdGenerator; use rustc_ast::ptr::P; use rustc_ast::token::{ @@ -1259,6 +1258,27 @@ impl<'a> State<'a> { fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) { self.print_formal_generic_params(&t.bound_generic_params); + + let ast::TraitBoundModifiers { constness, asyncness, polarity } = t.modifiers; + match constness { + ast::BoundConstness::Never => {} + ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => { + self.word_space(constness.as_str()); + } + } + match asyncness { + ast::BoundAsyncness::Normal => {} + ast::BoundAsyncness::Async(_) => { + self.word_space(asyncness.as_str()); + } + } + match polarity { + ast::BoundPolarity::Positive => {} + ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => { + self.word(polarity.as_str()); + } + } + self.print_trait_ref(&t.trait_ref) } @@ -1746,31 +1766,7 @@ impl<'a> State<'a> { } match bound { - GenericBound::Trait( - tref, - TraitBoundModifiers { constness, asyncness, polarity }, - ) => { - match constness { - ast::BoundConstness::Never => {} - ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => { - self.word_space(constness.as_str()); - } - } - - match asyncness { - ast::BoundAsyncness::Normal => {} - ast::BoundAsyncness::Async(_) => { - self.word_space(asyncness.as_str()); - } - } - - match polarity { - ast::BoundPolarity::Positive => {} - ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => { - self.word(polarity.as_str()); - } - } - + GenericBound::Trait(tref) => { self.print_poly_trait_ref(tref); } GenericBound::Outlives(lt) => self.print_lifetime(*lt), diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 39175b406a4aa..6333d59a1bc8d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -254,7 +254,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { debug!(?hrtb_bounds); hrtb_bounds.iter().for_each(|bound| { - let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else { + let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }) = bound else { return; }; diag.span_note(*trait_span, fluent::borrowck_limitations_implies_static); @@ -277,7 +277,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return; }; bounds.iter().for_each(|bd| { - if let Trait(PolyTraitRef { trait_ref: tr_ref, .. }, _) = bd + if let Trait(PolyTraitRef { trait_ref: tr_ref, .. }) = bd && let Def(_, res_defid) = tr_ref.path.res && res_defid == trait_res_defid // trait id matches && let TyKind::Path(Resolved(_, path)) = bounded_ty.kind diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 1a5f9bdb154c0..b4b8373ac9747 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -837,7 +837,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { hir_ty ); }; - if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref, _)], .. } = opaque_ty + if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref)], .. } = opaque_ty && let Some(segment) = trait_ref.trait_ref.path.segments.last() && let Some(args) = segment.args && let [constraint] = args.constraints diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs index e3878d90e4143..731945f5cbfbf 100644 --- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs +++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs @@ -333,12 +333,12 @@ fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee: } fn is_maybe_sized_bound(bound: &GenericBound) -> bool { - if let GenericBound::Trait( - trait_ref, - TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. }, - ) = bound + if let GenericBound::Trait(trait_ref) = bound + && let TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. } = + trait_ref.modifiers + && is_sized_marker(&trait_ref.trait_ref.path) { - is_sized_marker(&trait_ref.trait_ref.path) + true } else { false } diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 25583cda5a20d..43e2bf1796fc7 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -15,7 +15,7 @@ use rustc_span::symbol::{Ident, Symbol, kw, sym}; use thin_vec::thin_vec; use crate::errors; -use crate::util::{expr_to_string, get_exprs_from_tts, get_single_str_from_tts}; +use crate::util::{expr_to_string, get_exprs_from_tts, get_single_expr_from_tts}; fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result { let var = var.as_str(); @@ -32,19 +32,28 @@ pub(crate) fn expand_option_env<'cx>( sp: Span, tts: TokenStream, ) -> MacroExpanderResult<'cx> { - let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "option_env!") else { + let ExpandResult::Ready(mac_expr) = get_single_expr_from_tts(cx, sp, tts, "option_env!") else { + return ExpandResult::Retry(()); + }; + let var_expr = match mac_expr { + Ok(var_expr) => var_expr, + Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), + }; + let ExpandResult::Ready(mac) = + expr_to_string(cx, var_expr.clone(), "argument must be a string literal") + else { return ExpandResult::Retry(()); }; let var = match mac { - Ok(var) => var, + Ok((var, _)) => var, Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), }; let sp = cx.with_def_site_ctxt(sp); - let value = lookup_env(cx, var).ok(); - cx.sess.psess.env_depinfo.borrow_mut().insert((var, value)); + let value = lookup_env(cx, var); + cx.sess.psess.env_depinfo.borrow_mut().insert((var, value.as_ref().ok().copied())); let e = match value { - None => { + Err(VarError::NotPresent) => { let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp)); cx.expr_path(cx.path_all( sp, @@ -58,7 +67,18 @@ pub(crate) fn expand_option_env<'cx>( ))], )) } - Some(value) => { + Err(VarError::NotUnicode(_)) => { + let ExprKind::Lit(token::Lit { + kind: LitKind::Str | LitKind::StrRaw(..), symbol, .. + }) = &var_expr.kind + else { + unreachable!("`expr_to_string` ensures this is a string lit") + }; + + let guar = cx.dcx().emit_err(errors::EnvNotUnicode { span: sp, var: *symbol }); + return ExpandResult::Ready(DummyResult::any(sp, guar)); + } + Ok(value) => { cx.expr_call_global(sp, cx.std_path(&[sym::option, sym::Option, sym::Some]), thin_vec![ cx.expr_str(sp, value) ]) diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs index d7b03a43ecb0d..2a28dfaf3c430 100644 --- a/compiler/rustc_builtin_macros/src/util.rs +++ b/compiler/rustc_builtin_macros/src/util.rs @@ -171,6 +171,30 @@ pub(crate) fn get_single_str_spanned_from_tts( tts: TokenStream, name: &str, ) -> ExpandResult, ()> { + let ExpandResult::Ready(ret) = get_single_expr_from_tts(cx, span, tts, name) else { + return ExpandResult::Retry(()); + }; + let ret = match ret { + Ok(ret) => ret, + Err(e) => return ExpandResult::Ready(Err(e)), + }; + expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| { + res.map_err(|err| match err { + Ok((err, _)) => err.emit(), + Err(guar) => guar, + }) + .map(|(symbol, _style, span)| (symbol, span)) + }) +} + +/// Interpreting `tts` as a comma-separated sequence of expressions, +/// expect exactly one expression, or emit an error and return `Err`. +pub(crate) fn get_single_expr_from_tts( + cx: &mut ExtCtxt<'_>, + span: Span, + tts: TokenStream, + name: &str, +) -> ExpandResult, ErrorGuaranteed>, ()> { let mut p = cx.new_parser_from_tts(tts); if p.token == token::Eof { let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); @@ -185,13 +209,7 @@ pub(crate) fn get_single_str_spanned_from_tts( if p.token != token::Eof { cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); } - expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| { - res.map_err(|err| match err { - Ok((err, _)) => err.emit(), - Err(guar) => guar, - }) - .map(|(symbol, _style, span)| (symbol, span)) - }) + ExpandResult::Ready(Ok(ret)) } /// Extracts comma-separated expressions from `tts`. diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 743a9854f7964..a673e2e3250d5 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -143,24 +143,25 @@ impl<'a> ExtCtxt<'a> { ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID } } - pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { + pub fn poly_trait_ref(&self, span: Span, path: ast::Path, is_const: bool) -> ast::PolyTraitRef { ast::PolyTraitRef { bound_generic_params: ThinVec::new(), + modifiers: ast::TraitBoundModifiers { + polarity: ast::BoundPolarity::Positive, + constness: if is_const { + ast::BoundConstness::Maybe(DUMMY_SP) + } else { + ast::BoundConstness::Never + }, + asyncness: ast::BoundAsyncness::Normal, + }, trait_ref: self.trait_ref(path), span, } } pub fn trait_bound(&self, path: ast::Path, is_const: bool) -> ast::GenericBound { - ast::GenericBound::Trait(self.poly_trait_ref(path.span, path), ast::TraitBoundModifiers { - polarity: ast::BoundPolarity::Positive, - constness: if is_const { - ast::BoundConstness::Maybe(DUMMY_SP) - } else { - ast::BoundConstness::Never - }, - asyncness: ast::BoundAsyncness::Normal, - }) + ast::GenericBound::Trait(self.poly_trait_ref(path.span, path, is_const)) } pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index bc5ed249559a5..009c6c4aea558 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -519,7 +519,7 @@ pub enum TraitBoundModifier { #[derive(Clone, Copy, Debug, HashStable_Generic)] pub enum GenericBound<'hir> { - Trait(PolyTraitRef<'hir>, TraitBoundModifier), + Trait(PolyTraitRef<'hir>), Outlives(&'hir Lifetime), Use(&'hir [PreciseCapturingArg<'hir>], Span), } @@ -527,7 +527,7 @@ pub enum GenericBound<'hir> { impl GenericBound<'_> { pub fn trait_ref(&self) -> Option<&TraitRef<'_>> { match self { - GenericBound::Trait(data, _) => Some(&data.trait_ref), + GenericBound::Trait(data) => Some(&data.trait_ref), _ => None, } } @@ -2873,11 +2873,7 @@ pub enum TyKind<'hir> { OpaqueDef(&'hir OpaqueTy<'hir>, &'hir [GenericArg<'hir>]), /// A trait object type `Bound1 + Bound2 + Bound3` /// where `Bound` is a trait or a lifetime. - TraitObject( - &'hir [(PolyTraitRef<'hir>, TraitBoundModifier)], - &'hir Lifetime, - TraitObjectSyntax, - ), + TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax), /// Unused for now. Typeof(&'hir AnonConst), /// `TyKind::Infer` means the type should be inferred instead of it having been @@ -3181,6 +3177,11 @@ pub struct PolyTraitRef<'hir> { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: &'hir [GenericParam<'hir>], + /// The constness and polarity of the trait ref. + /// + /// The `async` modifier is lowered directly into a different trait for now. + pub modifiers: TraitBoundModifier, + /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`. pub trait_ref: TraitRef<'hir>, diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 58916d0586593..ffe519b0e7dd0 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -905,7 +905,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul try_visit!(visitor.visit_array_length(length)); } TyKind::TraitObject(bounds, ref lifetime, _syntax) => { - for (bound, _modifier) in bounds { + for bound in bounds { try_visit!(visitor.visit_poly_trait_ref(bound)); } try_visit!(visitor.visit_lifetime(lifetime)); @@ -1160,7 +1160,7 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>( bound: &'v GenericBound<'v>, ) -> V::Result { match *bound { - GenericBound::Trait(ref typ, _modifier) => visitor.visit_poly_trait_ref(typ), + GenericBound::Trait(ref typ) => visitor.visit_poly_trait_ref(typ), GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), GenericBound::Use(args, _) => { walk_list!(visitor, visit_precise_capturing_arg, args); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 4429f6346e88a..94da3d4ea8406 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -61,9 +61,9 @@ pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab Some(true) => (), Some(false) | None => { tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| { - lint.primary_message( - "use of calling convention not supported on this target on function pointer", - ); + lint.primary_message(format!( + "the calling convention {abi} is not supported on this target" + )); }); } } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3079fd71b0c2d..607068f162aa3 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -829,7 +829,7 @@ impl<'tcx> TypeVisitor> for GATArgsCollector<'tcx> { fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool { match ty.kind { - hir::TyKind::TraitObject([(trait_ref, _)], ..) => match trait_ref.trait_ref.path.segments { + hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments { [s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()), _ => false, }, diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 6d30f7c7b9d07..a87b29b3093d2 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -866,7 +866,7 @@ impl<'tcx> ItemCtxt<'tcx> { #[instrument(level = "trace", skip(self))] fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool { match b { - hir::GenericBound::Trait(poly_trait_ref, _) => { + hir::GenericBound::Trait(poly_trait_ref) => { let trait_ref = &poly_trait_ref.trait_ref; if let Some(trait_did) = trait_ref.trait_def_id() { self.tcx.trait_may_define_assoc_item(trait_did, assoc_name) diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index c8852a3a3695a..cb7f0901c7e4a 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -644,7 +644,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { debug!(?bounds, ?lifetime, "TraitObject"); let scope = Scope::TraitRefBoundary { s: self.scope }; self.with(scope, |this| { - for (bound, _) in bounds { + for bound in bounds { this.visit_poly_trait_ref_inner( bound, NonLifetimeBinderAllowed::Deny("trait object types"), @@ -1918,7 +1918,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { return None; } predicate.bounds.iter().find_map(|bound| { - let hir::GenericBound::Trait(trait_, _) = bound else { + let hir::GenericBound::Trait(trait_) = bound else { return None; }; BoundVarContext::supertrait_hrtb_vars( diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 45cd46e3df296..8f7ca089c9184 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -44,10 +44,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| { for hir_bound in hir_bounds { - let hir::GenericBound::Trait(ptr, modifier) = hir_bound else { + let hir::GenericBound::Trait(ptr) = hir_bound else { continue; }; - match modifier { + match ptr.modifiers { hir::TraitBoundModifier::Maybe => unbounds.push(ptr), hir::TraitBoundModifier::Negative => { if let Some(sized_def_id) = sized_def_id @@ -156,8 +156,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { { for hir_bound in hir_bounds { match hir_bound { - hir::GenericBound::Trait(poly_trait_ref, modifier) => { - let (constness, polarity) = match modifier { + hir::GenericBound::Trait(poly_trait_ref) => { + let (constness, polarity) = match poly_trait_ref.modifiers { hir::TraitBoundModifier::Const => { (ty::BoundConstness::Const, ty::PredicatePolarity::Positive) } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 394a263fbb595..98822eec2ac4d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -30,7 +30,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, span: Span, hir_id: hir::HirId, - hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)], + hir_trait_bounds: &[hir::PolyTraitRef<'tcx>], lifetime: &hir::Lifetime, representation: DynKind, ) -> Ty<'tcx> { @@ -39,8 +39,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut bounds = Bounds::default(); let mut potential_assoc_types = Vec::new(); let dummy_self = self.tcx().types.trait_object_dummy_self; - for (trait_bound, modifier) in hir_trait_bounds.iter().rev() { - if *modifier == hir::TraitBoundModifier::Maybe { + for trait_bound in hir_trait_bounds.iter().rev() { + // FIXME: This doesn't handle `? const`. + if trait_bound.modifiers == hir::TraitBoundModifier::Maybe { continue; } if let GenericArgCountResult { @@ -263,7 +264,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let args = tcx.mk_args(&args); let span = i.bottom().1; - let empty_generic_args = hir_trait_bounds.iter().any(|(hir_bound, _)| { + let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| { hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id) && hir_bound.span.contains(span) }); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index a735b8cc2a451..01768c89cca89 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -718,7 +718,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, associated_types: FxIndexMap>, potential_assoc_types: Vec, - trait_bounds: &[(hir::PolyTraitRef<'_>, hir::TraitBoundModifier)], + trait_bounds: &[hir::PolyTraitRef<'_>], ) { if associated_types.values().all(|v| v.is_empty()) { return; @@ -764,12 +764,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // related to issue #91997, turbofishes added only when in an expr or pat let mut in_expr_or_pat = false; if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) { - let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.0.trait_ref.hir_ref_id)); + let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id)); in_expr_or_pat = match grandparent { hir::Node::Expr(_) | hir::Node::Pat(_) => true, _ => false, }; - match bound.0.trait_ref.path.segments { + match bound.trait_ref.path.segments { // FIXME: `trait_ref.path.span` can point to a full path with multiple // segments, even though `trait_ref.path.segments` is of length `1`. Work // around that bug here, even though it should be fixed elsewhere. @@ -810,7 +810,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // and we can then use their span to indicate this to the user. let bound_names = trait_bounds .iter() - .filter_map(|(poly_trait_ref, _)| { + .filter_map(|poly_trait_ref| { let path = poly_trait_ref.trait_ref.path.segments.last()?; let args = path.args?; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 11c0450bfe211..fd49e7e44398b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -50,7 +50,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .ok() .is_some_and(|s| s.trim_end().ends_with('<')); - let is_global = poly_trait_ref.0.trait_ref.path.is_global(); + let is_global = poly_trait_ref.trait_ref.path.is_global(); let mut sugg = vec![( self_ty.span.shrink_to_lo(), @@ -211,7 +211,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Check if trait object is safe for suggesting dynamic dispatch. let is_dyn_compatible = match self_ty.kind { hir::TyKind::TraitObject(objects, ..) => { - objects.iter().all(|(o, _)| match o.trait_ref.path.res { + objects.iter().all(|o| match o.trait_ref.path.res { Res::Def(DefKind::Trait, id) => tcx.is_dyn_compatible(id), _ => false, }) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 9fe6a8ee3425a..9ebfd4f15abd3 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -301,16 +301,13 @@ impl<'a> State<'a> { self.word_space("dyn"); } let mut first = true; - for (bound, modifier) in bounds { + for bound in bounds { if first { first = false; } else { self.nbsp(); self.word_space("+"); } - if *modifier == TraitBoundModifier::Maybe { - self.word("?"); - } self.print_poly_trait_ref(bound); } if !lifetime.is_elided() { @@ -679,6 +676,10 @@ impl<'a> State<'a> { } fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef<'_>) { + // FIXME: This isn't correct! + if t.modifiers == TraitBoundModifier::Maybe { + self.word("?"); + } self.print_formal_generic_params(t.bound_generic_params); self.print_trait_ref(&t.trait_ref); } @@ -2077,10 +2078,7 @@ impl<'a> State<'a> { } match bound { - GenericBound::Trait(tref, modifier) => { - if modifier == &TraitBoundModifier::Maybe { - self.word("?"); - } + GenericBound::Trait(tref) => { self.print_poly_trait_ref(tref); } GenericBound::Outlives(lt) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 1df4d32f3cbac..3e9e53261562c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -849,7 +849,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::FnRetTy::Return(hir_ty) => { if let hir::TyKind::OpaqueDef(op_ty, ..) = hir_ty.kind // FIXME: account for RPITIT. - && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds + && let [hir::GenericBound::Trait(trait_ref)] = op_ty.bounds && let Some(hir::PathSegment { args: Some(generic_args), .. }) = trait_ref.trait_ref.path.segments.last() && let [constraint] = generic_args.constraints @@ -1035,7 +1035,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // extract all bounds from the source code using their spans let all_matching_bounds_strs = predicates_from_where .filter_map(|bound| match bound { - GenericBound::Trait(_, _) => { + GenericBound::Trait(_) => { self.tcx.sess.source_map().span_to_snippet(bound.span()).ok() } _ => None, diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index cb8b1df2c6e47..1b65dc8214cf1 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -199,6 +199,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, segment, span, call_expr, self_expr, &pick, args, ); + // NOTE: on the failure path, we also record the possibly-used trait methods + // since an unused import warning is kinda distracting from the method error. for &import_id in &pick.import_ids { debug!("used_trait_import: {:?}", import_id); self.typeck_results.borrow_mut().used_trait_imports.insert(import_id); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 4f726f3ed3866..05c8912aec12d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -191,6 +191,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Expectation<'tcx>, trait_missing_method: bool, ) -> ErrorGuaranteed { + // NOTE: Reporting a method error should also suppress any unused trait errors, + // since the method error is very possibly the reason why the trait wasn't used. + for &import_id in + self.tcx.in_scope_traits(call_id).into_iter().flatten().flat_map(|c| &c.import_ids) + { + self.typeck_results.borrow_mut().used_trait_imports.insert(import_id); + } + let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::MethodCall(segment, rcvr, args, _), diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml index 07ee81788ce46..a7c2a1804ddb8 100644 --- a/compiler/rustc_index_macros/Cargo.toml +++ b/compiler/rustc_index_macros/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" proc-macro = true [dependencies] -syn = { version = "2.0.9", features = ["full"] } +syn = { version = "2.0.9", features = ["full", "extra-traits"] } proc-macro2 = "1" quote = "1" diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index c0a01b0065ef9..5a3666dcbd432 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -112,10 +112,11 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) { let hir::TyKind::TraitObject(bounds, _lifetime, _syntax) = &ty.kind else { return }; - for (bound, modifier) in &bounds[..] { + for bound in &bounds[..] { let def_id = bound.trait_ref.trait_def_id(); if def_id.is_some_and(|def_id| cx.tcx.is_lang_item(def_id, LangItem::Drop)) - && *modifier != hir::TraitBoundModifier::Maybe + // FIXME: ?Drop is not a thing. + && bound.modifiers != hir::TraitBoundModifier::Maybe { let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return }; cx.emit_span_lint(DYN_DROP, bound.span, DropGlue { tcx: cx.tcx, def_id }); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 23dc5214fe2ea..da603df9a9a9f 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3859,7 +3859,7 @@ declare_lint! { /// This will produce: /// /// ```text - /// warning: use of calling convention not supported on this target on function pointer + /// warning: the calling convention `"stdcall"` is not supported on this target /// --> $DIR/unsupported.rs:34:15 /// | /// LL | fn stdcall_ptr(f: extern "stdcall" fn()) { diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 354ca746b466a..4f408ee157481 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -192,7 +192,8 @@ fn suggest_changing_unsized_bound( .iter() .enumerate() .filter(|(_, bound)| { - if let hir::GenericBound::Trait(poly, hir::TraitBoundModifier::Maybe) = bound + if let hir::GenericBound::Trait(poly) = bound + && poly.modifiers == hir::TraitBoundModifier::Maybe && poly.trait_ref.trait_def_id() == def_id { true diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f32307f6ed4d8..a9384501547e8 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2113,7 +2113,7 @@ impl<'a> Parser<'a> { && let Some(poly) = bounds .iter() .filter_map(|bound| match bound { - ast::GenericBound::Trait(poly, _) => Some(poly), + ast::GenericBound::Trait(poly) => Some(poly), _ => None, }) .last() diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 162ff3b94de52..2f19a9b6b20b4 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -948,8 +948,8 @@ impl<'a> Parser<'a> { { return Ok((false, seg.ident, seg.args.as_deref().cloned())); } else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind - && let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE)] = - bounds.as_slice() + && let [ast::GenericBound::Trait(trait_ref)] = bounds.as_slice() + && trait_ref.modifiers == ast::TraitBoundModifiers::NONE && let [seg] = trait_ref.trait_ref.path.segments.as_slice() { return Ok((true, seg.ident, seg.args.as_deref().cloned())); diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 48d29e84b2c49..c561ea3823d09 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -420,8 +420,13 @@ impl<'a> Parser<'a> { lo: Span, parse_plus: bool, ) -> PResult<'a, TyKind> { - let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span)); - let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifiers::NONE)]; + let poly_trait_ref = PolyTraitRef::new( + generic_params, + path, + TraitBoundModifiers::NONE, + lo.to(self.prev_token.span), + ); + let bounds = vec![GenericBound::Trait(poly_trait_ref)]; self.parse_remaining_bounds(bounds, parse_plus) } @@ -1117,8 +1122,9 @@ impl<'a> Parser<'a> { } } - let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_token.span)); - Ok(GenericBound::Trait(poly_trait, modifiers)) + let poly_trait = + PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span)); + Ok(GenericBound::Trait(poly_trait)) } // recovers a `Fn(..)` parenthesized-style path from `fn(..)` diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index e7ef4385baf4f..1716f417969e1 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -473,19 +473,19 @@ impl<'a> Parser<'a> { } pos = peek_pos; - description = format!("expected `'}}'`, found `{maybe:?}`"); + description = format!("expected `}}`, found `{}`", maybe.escape_debug()); } else { - description = "expected `'}'` but string was terminated".to_owned(); + description = "expected `}` but string was terminated".to_owned(); // point at closing `"` pos = self.input.len() - if self.append_newline { 1 } else { 0 }; } let pos = self.to_span_index(pos); - let label = "expected `'}'`".to_owned(); + let label = "expected `}`".to_owned(); let (note, secondary_label) = if arg.format.fill == Some('}') { ( - Some("the character `'}'` is interpreted as a fill character because of the `:` that precedes it".to_owned()), + Some("the character `}` is interpreted as a fill character because of the `:` that precedes it".to_owned()), arg.format.fill_span.map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)), ) } else { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index aced05ca351af..50fbdcaf9dc28 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -519,11 +519,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { continue; }; for bound in bounds { - let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE) = bound - else { + let ast::GenericBound::Trait(trait_ref) = bound else { continue; }; - if base_error.span == trait_ref.span { + if trait_ref.modifiers == ast::TraitBoundModifiers::NONE + && base_error.span == trait_ref.span + { err.span_suggestion_verbose( constraint.ident.span.between(trait_ref.span), "you might have meant to write a path instead of an associated type bound", @@ -837,7 +838,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ); if bounds.iter().all(|bound| match bound { ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true, - ast::GenericBound::Trait(tr, _) => tr.span == base_error.span, + ast::GenericBound::Trait(tr) => tr.span == base_error.span, }) { let mut sugg = vec![]; if base_error.span != start_span { @@ -1210,7 +1211,8 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let param = generics.params.iter().find_map(|param| { // Only consider type params with exactly one trait bound. if let [bound] = &*param.bounds - && let ast::GenericBound::Trait(tref, ast::TraitBoundModifiers::NONE) = bound + && let ast::GenericBound::Trait(tref) = bound + && tref.modifiers == ast::TraitBoundModifiers::NONE && tref.span == span && param.ident.span.eq_ctxt(span) { @@ -1333,8 +1335,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } if let ( [ast::PathSegment { args: None, .. }], - [ast::GenericBound::Trait(poly_trait_ref, ast::TraitBoundModifiers::NONE)], + [ast::GenericBound::Trait(poly_trait_ref)], ) = (&type_param_path.segments[..], &bounds[..]) + && poly_trait_ref.modifiers == ast::TraitBoundModifiers::NONE { if let [ast::PathSegment { ident, args: None, .. }] = &poly_trait_ref.trait_ref.path.segments[..] @@ -2814,7 +2817,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { && bounded_ty.id == binder { for bound in bounds { - if let ast::GenericBound::Trait(poly_trait_ref, _) = bound + if let ast::GenericBound::Trait(poly_trait_ref) = bound && let span = poly_trait_ref .span .with_hi(poly_trait_ref.trait_ref.path.span.lo()) @@ -3233,7 +3236,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let mut lt_finder = LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] }; for bound in arg_refs { - if let ast::GenericBound::Trait(trait_ref, _) = bound { + if let ast::GenericBound::Trait(trait_ref) = bound { lt_finder.visit_trait_ref(&trait_ref.trait_ref); } } @@ -3444,17 +3447,15 @@ fn mk_where_bound_predicate( span: DUMMY_SP, bound_generic_params: ThinVec::new(), bounded_ty: ast::ptr::P(ty.clone()), - bounds: vec![ast::GenericBound::Trait( - ast::PolyTraitRef { - bound_generic_params: ThinVec::new(), - trait_ref: ast::TraitRef { - path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None }, - ref_id: DUMMY_NODE_ID, - }, - span: DUMMY_SP, + bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef { + bound_generic_params: ThinVec::new(), + modifiers: ast::TraitBoundModifiers::NONE, + trait_ref: ast::TraitRef { + path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None }, + ref_id: DUMMY_NODE_ID, }, - ast::TraitBoundModifiers::NONE, - )], + span: DUMMY_SP, + })], }; Some(new_where_bound_predicate) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs index 7a44c2ad661dc..2ecd28f48681d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs @@ -86,7 +86,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { } hir::TyKind::TraitObject(bounds, ..) => { - for (bound, _) in bounds { + for bound in bounds { self.current_index.shift_in(1); self.visit_poly_trait_ref(bound); self.current_index.shift_out(1); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index a6ecd1cc9871b..8541621b23b87 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -599,7 +599,7 @@ impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> { _, ) = t.kind { - for (ptr, _) in poly_trait_refs { + for ptr in poly_trait_refs { if Some(self.1) == ptr.trait_ref.trait_def_id() { self.0.push(ptr.span); } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index cf0ab630f2e21..62204f63dd09a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -894,7 +894,9 @@ fn foo(&self) -> Self::T { String::new() } // FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting. let trait_bounds = bounds.iter().filter_map(|bound| match bound { - hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => Some(ptr), + hir::GenericBound::Trait(ptr) if ptr.modifiers == hir::TraitBoundModifier::None => { + Some(ptr) + } _ => None, }); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index 709b6eb18e35f..fc2d0ba36f04e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -740,9 +740,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match ( left, right, ) { - (hir::GenericBound::Trait(tl, ml), hir::GenericBound::Trait(tr, mr)) + // FIXME: Suspicious + (hir::GenericBound::Trait(tl), hir::GenericBound::Trait(tr)) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id() - && ml == mr => + && tl.modifiers == tr.modifiers => { true } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index becc1acfb6641..ba57909fc23a6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -439,7 +439,7 @@ pub fn report_dyn_incompatibility<'tcx>( if tcx.parent_hir_node(hir_id).fn_sig().is_some() { // Do not suggest `impl Trait` when dealing with things like super-traits. err.span_suggestion_verbose( - ty.span.until(trait_ref.0.span), + ty.span.until(trait_ref.span), "consider using an opaque type instead", "impl ", Applicability::MaybeIncorrect, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 87834c329e19f..733baaa99e52a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3074,11 +3074,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { match ty.kind { hir::TyKind::TraitObject(traits, _, _) => { let (span, kw) = match traits { - [(first, _), ..] if first.span.lo() == ty.span.lo() => { + [first, ..] if first.span.lo() == ty.span.lo() => { // Missing `dyn` in front of trait object. (ty.span.shrink_to_lo(), "dyn ") } - [(first, _), ..] => (ty.span.until(first.span), ""), + [first, ..] => (ty.span.until(first.span), ""), [] => span_bug!(ty.span, "trait object with no traits: {ty:?}"), }; let needs_parens = traits.len() != 1; @@ -5162,7 +5162,7 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>( let async_span = tcx.sess.source_map().span_extend_while_whitespace(async_span); let future = tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty(); - let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else { + let [hir::GenericBound::Trait(trait_ref)] = future.bounds else { // `async fn` should always lower to a single bound... but don't ICE. return None; }; diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 45e7de942fb61..364a13b3a7599 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -125,7 +125,7 @@ fn sized_trait_bound_spans<'tcx>( bounds: hir::GenericBounds<'tcx>, ) -> impl 'tcx + Iterator { bounds.iter().filter_map(move |b| match b { - hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) + hir::GenericBound::Trait(trait_ref) if trait_has_sized_self( tcx, trait_ref.trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()), diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index b5e5b58f7051f..6a4f2af10efc6 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1107,17 +1107,19 @@ pub(crate) mod builtin { /// /// If the named environment variable is present at compile time, this will /// expand into an expression of type `Option<&'static str>` whose value is - /// `Some` of the value of the environment variable. If the environment - /// variable is not present, then this will expand to `None`. See - /// [`Option`][Option] for more information on this type. Use - /// [`std::env::var`] instead if you want to read the value at runtime. + /// `Some` of the value of the environment variable (a compilation error + /// will be emitted if the environment variable is not a valid Unicode + /// string). If the environment variable is not present, then this will + /// expand to `None`. See [`Option`][Option] for more information on this + /// type. Use [`std::env::var`] instead if you want to read the value at + /// runtime. /// /// [`std::env::var`]: ../std/env/fn.var.html /// - /// A compile time error is never emitted when using this macro regardless - /// of whether the environment variable is present or not. - /// To emit a compile error if the environment variable is not present, - /// use the [`env!`] macro instead. + /// A compile time error is only emitted when using this macro if the + /// environment variable exists and is not a valid Unicode string. To also + /// emit a compile error if the environment variable is not present, use the + /// [`env!`] macro instead. /// /// # Examples /// diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index c9af7f13e46c4..0b0449d617490 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -63,21 +63,22 @@ impl *const T { self as _ } - /// Uses the pointer value in a new pointer of another type. + /// Uses the address value in a new pointer of another type. /// - /// In case `meta` is a (fat) pointer to an unsized type, this operation - /// will ignore the pointer part, whereas for (thin) pointers to sized - /// types, this has the same effect as a simple cast. + /// This operation will ignore the address part of its `meta` operand and discard existing + /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect + /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address + /// with new metadata such as slice lengths or `dyn`-vtable. /// - /// The resulting pointer will have provenance of `self`, i.e., for a fat - /// pointer, this operation is semantically the same as creating a new - /// fat pointer with the data pointer value of `self` but the metadata of - /// `meta`. + /// The resulting pointer will have provenance of `self`. This operation is semantically the + /// same as creating a new pointer with the data pointer value of `self` but the metadata of + /// `meta`, being fat or thin depending on the `meta` operand. /// /// # Examples /// - /// This function is primarily useful for allowing byte-wise pointer - /// arithmetic on potentially fat pointers: + /// This function is primarily useful for enabling pointer arithmetic on potentially fat + /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then + /// recombined with its own original metadata. /// /// ``` /// #![feature(set_ptr_value)] @@ -91,6 +92,26 @@ impl *const T { /// println!("{:?}", &*ptr); // will print "3" /// } /// ``` + /// + /// # *Incorrect* usage + /// + /// The provenance from pointers is *not* combined. The result must only be used to refer to the + /// address allowed by `self`. + /// + /// ```rust,no_run + /// #![feature(set_ptr_value)] + /// let x = 0u32; + /// let y = 1u32; + /// + /// let x = (&x) as *const u32; + /// let y = (&y) as *const u32; + /// + /// let offset = (x as usize - y as usize) / 4; + /// let bad = x.wrapping_add(offset).with_metadata_of(y); + /// + /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`. + /// println!("{:?}", unsafe { &*bad }); + /// ``` #[unstable(feature = "set_ptr_value", issue = "75091")] #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] #[must_use = "returns a new pointer rather than modifying its argument"] diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index ced6cb7d520de..8b61da74d02e7 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -45,21 +45,22 @@ impl *mut T { self as _ } - /// Uses the pointer value in a new pointer of another type. + /// Uses the address value in a new pointer of another type. /// - /// In case `meta` is a (fat) pointer to an unsized type, this operation - /// will ignore the pointer part, whereas for (thin) pointers to sized - /// types, this has the same effect as a simple cast. + /// This operation will ignore the address part of its `meta` operand and discard existing + /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect + /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address + /// with new metadata such as slice lengths or `dyn`-vtable. /// - /// The resulting pointer will have provenance of `self`, i.e., for a fat - /// pointer, this operation is semantically the same as creating a new - /// fat pointer with the data pointer value of `self` but the metadata of - /// `meta`. + /// The resulting pointer will have provenance of `self`. This operation is semantically the + /// same as creating a new pointer with the data pointer value of `self` but the metadata of + /// `meta`, being fat or thin depending on the `meta` operand. /// /// # Examples /// - /// This function is primarily useful for allowing byte-wise pointer - /// arithmetic on potentially fat pointers: + /// This function is primarily useful for enabling pointer arithmetic on potentially fat + /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then + /// recombined with its own original metadata. /// /// ``` /// #![feature(set_ptr_value)] @@ -73,6 +74,25 @@ impl *mut T { /// println!("{:?}", &*ptr); // will print "3" /// } /// ``` + /// + /// # *Incorrect* usage + /// + /// The provenance from pointers is *not* combined. The result must only be used to refer to the + /// address allowed by `self`. + /// + /// ```rust,no_run + /// #![feature(set_ptr_value)] + /// let mut x = 0u32; + /// let mut y = 1u32; + /// + /// let x = (&mut x) as *mut u32; + /// let y = (&mut y) as *mut u32; + /// + /// let offset = (x as usize - y as usize) / 4; + /// let bad = x.wrapping_add(offset).with_metadata_of(y); + /// + /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`. + /// println!("{:?}", unsafe { &*bad }); #[unstable(feature = "set_ptr_value", issue = "75091")] #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] #[must_use = "returns a new pointer rather than modifying its argument"] diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fa73733360ca1..1ddad917b783c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -214,15 +214,15 @@ fn clean_generic_bound<'tcx>( ) -> Option { Some(match *bound { hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)), - hir::GenericBound::Trait(ref t, modifier) => { + hir::GenericBound::Trait(ref t) => { // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op. - if modifier == hir::TraitBoundModifier::MaybeConst + if t.modifiers == hir::TraitBoundModifier::MaybeConst && cx.tcx.lang_items().destruct_trait() == Some(t.trait_ref.trait_def_id().unwrap()) { return None; } - GenericBound::TraitBound(clean_poly_trait_ref(t, cx), modifier) + GenericBound::TraitBound(clean_poly_trait_ref(t, cx), t.modifiers) } hir::GenericBound::Use(args, ..) => { GenericBound::Use(args.iter().map(|arg| arg.name()).collect()) @@ -1833,7 +1833,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } TyKind::Path(_) => clean_qpath(ty, cx), TyKind::TraitObject(bounds, lifetime, _) => { - let bounds = bounds.iter().map(|(bound, _)| clean_poly_trait_ref(bound, cx)).collect(); + let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect(); let lifetime = if !lifetime.is_elided() { Some(clean_lifetime(lifetime, cx)) } else { None }; DynTrait(bounds, lifetime) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index d5bc2a93fa807..7b2a5eb3d637a 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -643,8 +643,7 @@ fn run_test( } else { cmd = Command::new(&output_file); if doctest.is_multiple_tests { - cmd.arg("*doctest-bin-path"); - cmd.arg(&output_file); + cmd.env("RUSTDOC_DOCTEST_BIN_PATH", &output_file); } } if let Some(run_directory) = &rustdoc_options.test_run_directory { diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs index 942ec8d9936cf..093755103f36a 100644 --- a/src/librustdoc/doctest/runner.rs +++ b/src/librustdoc/doctest/runner.rs @@ -112,8 +112,7 @@ mod __doctest_mod {{ use std::path::PathBuf; pub static BINARY_PATH: OnceLock = OnceLock::new(); - pub const RUN_OPTION: &str = \"*doctest-inner-test\"; - pub const BIN_OPTION: &str = \"*doctest-bin-path\"; + pub const RUN_OPTION: &str = \"RUSTDOC_DOCTEST_RUN_NB_TEST\"; #[allow(unused)] pub fn doctest_path() -> Option<&'static PathBuf> {{ @@ -123,8 +122,8 @@ mod __doctest_mod {{ #[allow(unused)] pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> Result<(), String> {{ let out = std::process::Command::new(bin) - .arg(self::RUN_OPTION) - .arg(test_nb.to_string()) + .env(self::RUN_OPTION, test_nb.to_string()) + .args(std::env::args().skip(1).collect::>()) .output() .expect(\"failed to run command\"); if !out.status.success() {{ @@ -138,36 +137,27 @@ mod __doctest_mod {{ #[rustc_main] fn main() -> std::process::ExitCode {{ const TESTS: [test::TestDescAndFn; {nb_tests}] = [{ids}]; -let bin_marker = std::ffi::OsStr::new(__doctest_mod::BIN_OPTION); let test_marker = std::ffi::OsStr::new(__doctest_mod::RUN_OPTION); let test_args = &[{test_args}]; +const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\"; -let mut args = std::env::args_os().skip(1); -while let Some(arg) = args.next() {{ - if arg == bin_marker {{ - let Some(binary) = args.next() else {{ - panic!(\"missing argument after `{{}}`\", __doctest_mod::BIN_OPTION); - }}; - if crate::__doctest_mod::BINARY_PATH.set(binary.into()).is_err() {{ - panic!(\"`{{}}` option was used more than once\", bin_marker.to_string_lossy()); - }} - return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)); - }} else if arg == test_marker {{ - let Some(nb_test) = args.next() else {{ - panic!(\"missing argument after `{{}}`\", __doctest_mod::RUN_OPTION); - }}; - if let Some(nb_test) = nb_test.to_str().and_then(|nb| nb.parse::().ok()) {{ - if let Some(test) = TESTS.get(nb_test) {{ - if let test::StaticTestFn(f) = test.testfn {{ - return std::process::Termination::report(f()); - }} +if let Ok(binary) = std::env::var(ENV_BIN) {{ + let _ = crate::__doctest_mod::BINARY_PATH.set(binary.into()); + unsafe {{ std::env::remove_var(ENV_BIN); }} + return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)); +}} else if let Ok(nb_test) = std::env::var(__doctest_mod::RUN_OPTION) {{ + if let Ok(nb_test) = nb_test.parse::() {{ + if let Some(test) = TESTS.get(nb_test) {{ + if let test::StaticTestFn(f) = test.testfn {{ + return std::process::Termination::report(f()); }} }} - panic!(\"Unexpected value after `{{}}`\", __doctest_mod::RUN_OPTION); }} + panic!(\"Unexpected value for `{{}}`\", __doctest_mod::RUN_OPTION); }} -eprintln!(\"WARNING: No argument provided so doctests will be run in the same process\"); +eprintln!(\"WARNING: No rustdoc doctest environment variable provided so doctests will be run in \ +the same process\"); std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)) }}", nb_tests = self.nb_tests, diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs index 5f349d780537b..590d9afd1b437 100644 --- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs +++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs @@ -242,7 +242,8 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds bounds .iter() .filter_map(|bound| { - if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound + if let GenericBound::Trait(poly_trait) = bound + && let TraitBoundModifier::None = poly_trait.modifiers && let [.., path] = poly_trait.trait_ref.path.segments && poly_trait.bound_generic_params.is_empty() && let Some(trait_def_id) = path.res.opt_def_id() @@ -307,7 +308,8 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) { // This involves some extra logic when generic arguments are present, since // simply comparing trait `DefId`s won't be enough. We also need to compare the generics. for (index, bound) in bounds.iter().enumerate() { - if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound + if let GenericBound::Trait(poly_trait) = bound + && let TraitBoundModifier::None = poly_trait.modifiers && let [.., path] = poly_trait.trait_ref.path.segments && let implied_args = path.args.map_or([].as_slice(), |a| a.args) && let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints) diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 311bbce14bd7e..035ee40348c77 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -310,7 +310,7 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<& if let ty::Alias(_, alias_ty) = ty.kind() && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id) && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin - && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds + && let [GenericBound::Trait(trait_ref)] = &opaque.bounds && let Some(segment) = trait_ref.trait_ref.path.segments.last() && let Some(generic_args) = segment.args && let [constraint] = generic_args.constraints diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index ec28671a061e4..a7c48eb216aa4 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -163,7 +163,7 @@ fn check_fn_inner<'tcx>( if visitor.lts.iter().any(|lt| matches!(lt.res, LifetimeName::Param(_))) { return; } - if let GenericBound::Trait(ref trait_ref, _) = *bound { + if let GenericBound::Trait(ref trait_ref) = *bound { let params = &trait_ref .trait_ref .path @@ -438,7 +438,7 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> { if !lt.is_elided() { self.unelided_trait_object_lifetime = true; } - for (bound, _) in bounds { + for bound in bounds { self.visit_poly_trait_ref(bound); } }, diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index 81115cffdca88..67255c1af7933 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -107,7 +107,7 @@ fn future_trait_ref<'tcx>( ) -> Option<(&'tcx TraitRef<'tcx>, Vec)> { if let TyKind::OpaqueDef(opaque, bounds) = ty.kind && let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| { - if let GenericBound::Trait(poly, _) = bound { + if let GenericBound::Trait(poly) = bound { Some(&poly.trait_ref) } else { None diff --git a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs index bb44ff37b203b..a56024f08d509 100644 --- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs +++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs @@ -40,7 +40,6 @@ struct Bound<'tcx> { ident: Ident, trait_bound: &'tcx PolyTraitRef<'tcx>, - modifier: TraitBoundModifier, predicate_pos: usize, bound_pos: usize, @@ -65,11 +64,10 @@ fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator Some(Bound { + &GenericBound::Trait(ref trait_bound) => Some(Bound { param, ident, trait_bound, - modifier, predicate_pos, bound_pos, }), @@ -120,13 +118,13 @@ impl LateLintPass<'_> for NeedlessMaybeSized { let maybe_sized_params: DefIdMap<_> = type_param_bounds(generics) .filter(|bound| { bound.trait_bound.trait_ref.trait_def_id() == Some(sized_trait) - && bound.modifier == TraitBoundModifier::Maybe + && bound.trait_bound.modifiers == TraitBoundModifier::Maybe }) .map(|bound| (bound.param, bound)) .collect(); for bound in type_param_bounds(generics) { - if bound.modifier == TraitBoundModifier::None + if bound.trait_bound.modifiers == TraitBoundModifier::None && let Some(sized_bound) = maybe_sized_params.get(&bound.param) && let Some(path) = path_to_sized_bound(cx, bound.trait_bound) { diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index 3c3973857e796..38befdee57478 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -182,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { // Iterate the bounds and add them to our seen hash // If we haven't yet seen it, add it to the fixed traits - for (bound, _) in bounds { + for bound in bounds { let Some(def_id) = bound.trait_ref.trait_def_id() else { continue; }; @@ -197,9 +197,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { // If the number of unique traits isn't the same as the number of traits in the bounds, // there must be 1 or more duplicates if bounds.len() != unique_traits.len() { - let mut bounds_span = bounds[0].0.span; + let mut bounds_span = bounds[0].span; - for (bound, _) in bounds.iter().skip(1) { + for bound in bounds.iter().skip(1) { bounds_span = bounds_span.to(bound.span); } @@ -229,7 +229,8 @@ impl TraitBounds { /// this MSRV? See for details. fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool { if !self.msrv.meets(msrvs::MAYBE_BOUND_IN_WHERE) - && let GenericBound::Trait(tr, TraitBoundModifier::Maybe) = bound + && let GenericBound::Trait(tr) = bound + && let TraitBoundModifier::Maybe = tr.modifiers { cx.tcx.lang_items().get(LangItem::Sized) == tr.trait_ref.path.res.opt_def_id() } else { @@ -375,11 +376,11 @@ impl Default for ComparableTraitRef { } fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'a [PathSegment<'a>], Span)> { - if let GenericBound::Trait(t, tbm) = bound { + if let GenericBound::Trait(t) = bound { let trait_path = t.trait_ref.path; let trait_span = { let path_span = trait_path.span; - if let TraitBoundModifier::Maybe = tbm { + if let TraitBoundModifier::Maybe = t.modifiers { path_span.with_lo(path_span.lo() - BytePos(1)) // include the `?` } else { path_span @@ -430,7 +431,7 @@ fn rollup_traits( let mut repeated_res = false; let only_comparable_trait_refs = |bound: &GenericBound<'_>| { - if let GenericBound::Trait(t, _) = bound { + if let GenericBound::Trait(t) = bound { Some((into_comparable_trait_ref(&t.trait_ref), t.span)) } else { None diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs index 2fcfc71a8c768..eb7ffbbe360d5 100644 --- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs +++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs @@ -82,7 +82,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m // Returns true if given type is `Any` trait. fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool { if let TyKind::TraitObject(traits, ..) = t.kind { - return traits.iter().any(|(bound, _)| { + return traits.iter().any(|bound| { if let Some(trait_did) = bound.trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::Any, trait_did) { diff --git a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs index 0b64fddb447b5..b89bd6a8d0589 100644 --- a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs @@ -55,7 +55,6 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { TyKind::TraitObject(param_bounds, _, _) => { let has_lifetime_parameters = param_bounds.iter().any(|bound| { bound - .0 .bound_generic_params .iter() .any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. })) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 187f7fb441761..0be6dc15a8e13 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -786,7 +786,8 @@ pub fn eq_str_lit(l: &StrLit, r: &StrLit) -> bool { } pub fn eq_poly_ref_trait(l: &PolyTraitRef, r: &PolyTraitRef) -> bool { - eq_path(&l.trait_ref.path, &r.trait_ref.path) + l.modifiers == r.modifiers + && eq_path(&l.trait_ref.path, &r.trait_ref.path) && over(&l.bound_generic_params, &r.bound_generic_params, |l, r| { eq_generic_param(l, r) }) @@ -820,7 +821,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool { pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool { use GenericBound::*; match (l, r) { - (Trait(ptr1, tbm1), Trait(ptr2, tbm2)) => tbm1 == tbm2 && eq_poly_ref_trait(ptr1, ptr2), + (Trait(ptr1), Trait(ptr2)) => eq_poly_ref_trait(ptr1, ptr2), (Outlives(l), Outlives(r)) => eq_id(l.ident, r.ident), _ => false, } diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index a5418ad838488..1ee00a3a4e8ff 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -759,14 +759,8 @@ pub fn output_testname_unique( /// test/revision should reside. Example: /// /path/to/build/host-triple/test/ui/relative/testname.revision.mode/ pub fn output_base_dir(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf { - // In run-make tests, constructing a relative path + unique testname causes a double layering - // since revisions are not supported, causing unnecessary nesting. - if config.mode == Mode::RunMake { - output_relative_path(config, &testpaths.relative_dir) - } else { - output_relative_path(config, &testpaths.relative_dir) - .join(output_testname_unique(config, testpaths, revision)) - } + output_relative_path(config, &testpaths.relative_dir) + .join(output_testname_unique(config, testpaths, revision)) } /// Absolute path to the base filename used as output for the given diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 860d21876de0f..328b48e04d2e6 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -235,7 +235,9 @@ def update_latest( exit(0) cur_commit = sys.argv[1] - cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') + cur_datetime = datetime.datetime.now(datetime.timezone.utc).strftime( + '%Y-%m-%dT%H:%M:%SZ' + ) cur_commit_msg = sys.argv[2] save_message_to_path = sys.argv[3] github_token = sys.argv[4] diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index 555a924079879..4d684f3c6350d 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -180,7 +180,7 @@ impl Spanned for ast::GenericArg { impl Spanned for ast::GenericBound { fn span(&self) -> Span { match *self { - ast::GenericBound::Trait(ref ptr, _) => ptr.span, + ast::GenericBound::Trait(ref ptr) => ptr.span, ast::GenericBound::Outlives(ref l) => l.ident.span, ast::GenericBound::Use(_, span) => span, } diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 10027dc3d6943..99b3fe60ee2fa 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -610,16 +610,14 @@ impl Rewrite for ast::GenericBound { fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { match *self { - ast::GenericBound::Trait( - ref poly_trait_ref, - ast::TraitBoundModifiers { + ast::GenericBound::Trait(ref poly_trait_ref) => { + let snippet = context.snippet(self.span()); + let has_paren = snippet.starts_with('(') && snippet.ends_with(')'); + let ast::TraitBoundModifiers { constness, asyncness, polarity, - }, - ) => { - let snippet = context.snippet(self.span()); - let has_paren = snippet.starts_with('(') && snippet.ends_with(')'); + } = poly_trait_ref.modifiers; let mut constness = constness.as_str().to_string(); if !constness.is_empty() { constness.push(' '); diff --git a/tests/run-make/README.md b/tests/run-make/README.md index 4035990347389..9e1eaa881c946 100644 --- a/tests/run-make/README.md +++ b/tests/run-make/README.md @@ -29,7 +29,7 @@ The setup for the `rmake.rs` version is a 3-stage process: structure within `build//test/run-make/` ``` - / + // rmake.exe # recipe binary rmake_out/ # sources from test sources copied over ``` diff --git a/tests/run-make/non-unicode-env/non_unicode_env.rs b/tests/run-make/non-unicode-env/non_unicode_env.rs index 865fc93736578..3efa4842d94a5 100644 --- a/tests/run-make/non-unicode-env/non_unicode_env.rs +++ b/tests/run-make/non-unicode-env/non_unicode_env.rs @@ -1,3 +1,4 @@ fn main() { let _ = env!("NON_UNICODE_VAR"); + let _ = option_env!("NON_UNICODE_VAR"); } diff --git a/tests/run-make/non-unicode-env/non_unicode_env.stderr b/tests/run-make/non-unicode-env/non_unicode_env.stderr index c4dcd7b2eb707..1f260ac9c07bd 100644 --- a/tests/run-make/non-unicode-env/non_unicode_env.stderr +++ b/tests/run-make/non-unicode-env/non_unicode_env.stderr @@ -6,5 +6,13 @@ error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string | = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error +error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string + --> non_unicode_env.rs:3:13 + | +3 | let _ = option_env!("NON_UNICODE_VAR"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `option_env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index e8cec6321772d..1577b68e748f5 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -178,7 +178,7 @@ struct ErrorWithNonexistentField { } #[derive(Diagnostic)] -//~^ ERROR invalid format string: expected `'}'` +//~^ ERROR invalid format string: expected `}` #[diag(no_crate_example, code = E0123)] struct ErrorMissingClosingBrace { #[suggestion(no_crate_suggestion, code = "{name")] diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 97f9896f3a72a..ff7af38851489 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -184,11 +184,11 @@ error: `name` doesn't refer to a field on this type LL | #[suggestion(no_crate_suggestion, code = "{name}")] | ^^^^^^^^ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/diagnostic-derive.rs:180:10 | LL | #[derive(Diagnostic)] - | ^^^^^^^^^^ expected `'}'` in format string + | ^^^^^^^^^^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 00a5b4b2ee142..82908ef88a8b7 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -104,7 +104,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -123,7 +123,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -132,7 +132,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index dfb5ceb0c3370..39ec5d16fcd0d 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index 6537ce6605770..1dc01a66aabc4 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -83,7 +83,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index a53f85f28bcee..e7d5197feebbe 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index a53f85f28bcee..e7d5197feebbe 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 45ba9a6649c51..bbca754dd41f4 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs index 8d8917fd319cb..3ca58b28181cb 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs +++ b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs @@ -19,8 +19,8 @@ trait ImportantTrait3 {} trait ImportantTrait4 {} #[diagnostic::on_unimplemented(message = "Test {Self:!}")] -//~^WARN expected `'}'`, found `'!'` -//~|WARN expected `'}'`, found `'!'` +//~^WARN expected `}`, found `!` +//~|WARN expected `}`, found `!` //~|WARN unmatched `}` found //~|WARN unmatched `}` found trait ImportantTrait5 {} diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr index 932e81ca48e49..b4ed06cb63d8f 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr @@ -30,7 +30,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")] | = help: no format specifier are supported in this position -warning: expected `'}'`, found `'!'` +warning: expected `}`, found `!` --> $DIR/broken_format.rs:21:32 | LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")] @@ -153,7 +153,7 @@ note: required by a bound in `check_4` LL | fn check_4(_: impl ImportantTrait4) {} | ^^^^^^^^^^^^^^^ required by this bound in `check_4` -warning: expected `'}'`, found `'!'` +warning: expected `}`, found `!` --> $DIR/broken_format.rs:21:32 | LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")] diff --git a/tests/ui/fmt/closing-brace-as-fill.rs b/tests/ui/fmt/closing-brace-as-fill.rs index 6ad257f943e93..5865ee31c43df 100644 --- a/tests/ui/fmt/closing-brace-as-fill.rs +++ b/tests/ui/fmt/closing-brace-as-fill.rs @@ -4,5 +4,5 @@ fn main() { println!("Hello, world! {0:}<3", 2); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated } diff --git a/tests/ui/fmt/closing-brace-as-fill.stderr b/tests/ui/fmt/closing-brace-as-fill.stderr index 70068fa3aadc4..aa22beddf45a6 100644 --- a/tests/ui/fmt/closing-brace-as-fill.stderr +++ b/tests/ui/fmt/closing-brace-as-fill.stderr @@ -1,12 +1,12 @@ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/closing-brace-as-fill.rs:6:35 | LL | println!("Hello, world! {0:}<3", 2); - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | this is not interpreted as a formatting closing brace | - = note: the character `'}'` is interpreted as a fill character because of the `:` that precedes it + = note: the character `}` is interpreted as a fill character because of the `:` that precedes it error: aborting due to 1 previous error diff --git a/tests/ui/fmt/format-string-error-2.rs b/tests/ui/fmt/format-string-error-2.rs index 1f7f0d8f6be6a..357dd7b10a3e2 100644 --- a/tests/ui/fmt/format-string-error-2.rs +++ b/tests/ui/fmt/format-string-error-2.rs @@ -72,7 +72,7 @@ raw { \n // note: `\x7B` is `{` println!("\x7B}\u{8} {", 1); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated println!("\x7B}\u8 {", 1); //~^ ERROR incorrect unicode escape sequence diff --git a/tests/ui/fmt/format-string-error-2.stderr b/tests/ui/fmt/format-string-error-2.stderr index d5fe4081ac811..a2d142e0baba8 100644 --- a/tests/ui/fmt/format-string-error-2.stderr +++ b/tests/ui/fmt/format-string-error-2.stderr @@ -9,138 +9,138 @@ help: format of unicode escape sequences uses braces LL | println!("\x7B}\u{8} {", 1); | ~~~~~ -error: invalid format string: expected `'}'`, found `'a'` +error: invalid format string: expected `}`, found `a` --> $DIR/format-string-error-2.rs:5:5 | LL | format!("{ | - because of this opening brace LL | a"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'b'` +error: invalid format string: expected `}`, found `b` --> $DIR/format-string-error-2.rs:9:5 | LL | format!("{ \ | - because of this opening brace LL | \ LL | b"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'\'` +error: invalid format string: expected `}`, found `\` --> $DIR/format-string-error-2.rs:11:18 | LL | format!(r#"{ \ - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'\'` +error: invalid format string: expected `}`, found `\` --> $DIR/format-string-error-2.rs:15:18 | LL | format!(r#"{ \n - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'e'` +error: invalid format string: expected `}`, found `e` --> $DIR/format-string-error-2.rs:21:5 | LL | format!("{ \n | - because of this opening brace LL | \n LL | e"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'a'` +error: invalid format string: expected `}`, found `a` --> $DIR/format-string-error-2.rs:25:5 | LL | { | - because of this opening brace LL | a"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'a'` +error: invalid format string: expected `}`, found `a` --> $DIR/format-string-error-2.rs:29:5 | LL | { | - because of this opening brace LL | a - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'b'` +error: invalid format string: expected `}`, found `b` --> $DIR/format-string-error-2.rs:35:5 | LL | { \ | - because of this opening brace LL | \ LL | b"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'b'` +error: invalid format string: expected `}`, found `b` --> $DIR/format-string-error-2.rs:40:5 | LL | { \ | - because of this opening brace LL | \ LL | b \ - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'\'` +error: invalid format string: expected `}`, found `\` --> $DIR/format-string-error-2.rs:45:8 | LL | raw { \ - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'\'` +error: invalid format string: expected `}`, found `\` --> $DIR/format-string-error-2.rs:50:8 | LL | raw { \n - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'e'` +error: invalid format string: expected `}`, found `e` --> $DIR/format-string-error-2.rs:57:5 | LL | { \n | - because of this opening brace LL | \n LL | e"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'a'` +error: invalid format string: expected `}`, found `a` --> $DIR/format-string-error-2.rs:67:5 | LL | { | - because of this opening brace LL | asdf} - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` @@ -150,11 +150,11 @@ error: 1 positional argument in format string, but no arguments were given LL | println!("\t{}"); | ^^ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error-2.rs:74:27 | LL | println!("\x7B}\u{8} {", 1); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | diff --git a/tests/ui/fmt/format-string-error.rs b/tests/ui/fmt/format-string-error.rs index 9b436e2c479f2..cb9449be53207 100644 --- a/tests/ui/fmt/format-string-error.rs +++ b/tests/ui/fmt/format-string-error.rs @@ -2,7 +2,7 @@ fn main() { println!("{"); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated println!("{{}}"); println!("}"); //~^ ERROR invalid format string: unmatched `}` found @@ -13,11 +13,11 @@ fn main() { let _ = format!("{a:._$}", a = "", _ = 0); //~^ ERROR invalid format string: invalid argument name `_` let _ = format!("{"); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated let _ = format!("}"); //~^ ERROR invalid format string: unmatched `}` found let _ = format!("{\\}"); - //~^ ERROR invalid format string: expected `'}'`, found `'\'` + //~^ ERROR invalid format string: expected `}`, found `\` let _ = format!("\n\n\n{\n\n\n"); //~^ ERROR invalid format string let _ = format!(r###" diff --git a/tests/ui/fmt/format-string-error.stderr b/tests/ui/fmt/format-string-error.stderr index 37a181e6fcb23..9d6a91413d004 100644 --- a/tests/ui/fmt/format-string-error.stderr +++ b/tests/ui/fmt/format-string-error.stderr @@ -1,8 +1,8 @@ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error.rs:4:16 | LL | println!("{"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | @@ -40,11 +40,11 @@ LL | let _ = format!("{a:._$}", a = "", _ = 0); | = note: argument name cannot be a single underscore -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error.rs:15:23 | LL | let _ = format!("{"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | @@ -58,44 +58,44 @@ LL | let _ = format!("}"); | = note: if you intended to print `}`, you can escape it using `}}` -error: invalid format string: expected `'}'`, found `'\'` +error: invalid format string: expected `}`, found `\` --> $DIR/format-string-error.rs:19:23 | LL | let _ = format!("{\}"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error.rs:21:35 | LL | let _ = format!("\n\n\n{\n\n\n"); - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error.rs:27:3 | LL | {"###); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error.rs:35:1 | LL | { | - because of this opening brace LL | LL | "###); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` diff --git a/tests/ui/fmt/format-string-wrong-order.rs b/tests/ui/fmt/format-string-wrong-order.rs index da775be3ffd67..891279b97e4d3 100644 --- a/tests/ui/fmt/format-string-wrong-order.rs +++ b/tests/ui/fmt/format-string-wrong-order.rs @@ -7,9 +7,9 @@ fn main() { format!("{?:?}", bar); //~^ ERROR invalid format string: expected format parameter to occur after `:` format!("{??}", bar); - //~^ ERROR invalid format string: expected `'}'`, found `'?'` + //~^ ERROR invalid format string: expected `}`, found `?` format!("{?;bar}"); - //~^ ERROR invalid format string: expected `'}'`, found `'?'` + //~^ ERROR invalid format string: expected `}`, found `?` format!("{?:#?}", bar); //~^ ERROR invalid format string: expected format parameter to occur after `:` format!("Hello {<5:}!", "x"); diff --git a/tests/ui/fmt/format-string-wrong-order.stderr b/tests/ui/fmt/format-string-wrong-order.stderr index 3ef07720c153e..7f017511761f5 100644 --- a/tests/ui/fmt/format-string-wrong-order.stderr +++ b/tests/ui/fmt/format-string-wrong-order.stderr @@ -22,21 +22,21 @@ LL | format!("{?:?}", bar); | = note: `?` comes after `:`, try `:?` instead -error: invalid format string: expected `'}'`, found `'?'` +error: invalid format string: expected `}`, found `?` --> $DIR/format-string-wrong-order.rs:9:15 | LL | format!("{??}", bar); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'?'` +error: invalid format string: expected `}`, found `?` --> $DIR/format-string-wrong-order.rs:11:15 | LL | format!("{?;bar}"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | diff --git a/tests/ui/fmt/ifmt-bad-arg.rs b/tests/ui/fmt/ifmt-bad-arg.rs index 68861d7bf3faf..e39ffb8fe1b36 100644 --- a/tests/ui/fmt/ifmt-bad-arg.rs +++ b/tests/ui/fmt/ifmt-bad-arg.rs @@ -48,7 +48,7 @@ fn main() { // bad syntax of the format string - format!("{"); //~ ERROR: expected `'}'` but string was terminated + format!("{"); //~ ERROR: expected `}` but string was terminated format!("foo } bar"); //~ ERROR: unmatched `}` found format!("foo }"); //~ ERROR: unmatched `}` found diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr index 09ce3dca4117e..4344aee83c2b1 100644 --- a/tests/ui/fmt/ifmt-bad-arg.stderr +++ b/tests/ui/fmt/ifmt-bad-arg.stderr @@ -136,11 +136,11 @@ LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | | | formatting specifier missing -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/ifmt-bad-arg.rs:51:15 | LL | format!("{"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | @@ -172,13 +172,13 @@ LL | format!("foo %s baz", "bar"); | = note: printf formatting is not supported; see the documentation for `std::fmt` -error: invalid format string: expected `'}'`, found `'t'` +error: invalid format string: expected `}`, found `t` --> $DIR/ifmt-bad-arg.rs:75:1 | LL | ninth number: { | - because of this opening brace LL | tenth number: {}", - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` diff --git a/tests/ui/fmt/issue-91556.rs b/tests/ui/fmt/issue-91556.rs index e782e6f907631..fcf8909859c60 100644 --- a/tests/ui/fmt/issue-91556.rs +++ b/tests/ui/fmt/issue-91556.rs @@ -1,8 +1,8 @@ fn main() { let _ = format!(concat!("{0}π–³π–Ύπ—Œπ—{"), i); - //~^ ERROR: invalid format string: expected `'}'` but string was terminated + //~^ ERROR: invalid format string: expected `}` but string was terminated //~| NOTE: if you intended to print `{`, you can escape it using `{{` //~| NOTE: in this expansion of concat! //~| NOTE: in this expansion of concat! - //~| NOTE: expected `'}'` in format string + //~| NOTE: expected `}` in format string } diff --git a/tests/ui/fmt/issue-91556.stderr b/tests/ui/fmt/issue-91556.stderr index beab3db0d94c1..52917fb8c4247 100644 --- a/tests/ui/fmt/issue-91556.stderr +++ b/tests/ui/fmt/issue-91556.stderr @@ -1,8 +1,8 @@ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/issue-91556.rs:2:19 | LL | let _ = format!(concat!("{0}π–³π–Ύπ—Œπ—{"), i); - | ^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string + | ^^^^^^^^^^^^^^^^^^^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/fmt/respanned-literal-issue-106191.rs b/tests/ui/fmt/respanned-literal-issue-106191.rs index b0c0855a87093..0a127b1a0ca2a 100644 --- a/tests/ui/fmt/respanned-literal-issue-106191.rs +++ b/tests/ui/fmt/respanned-literal-issue-106191.rs @@ -4,7 +4,7 @@ extern crate format_string_proc_macro; fn main() { format_string_proc_macro::respan_to_invalid_format_literal!("Β‘"); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated format_args!(r#concat!("Β‘ {")); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated } diff --git a/tests/ui/fmt/respanned-literal-issue-106191.stderr b/tests/ui/fmt/respanned-literal-issue-106191.stderr index 73a3af65a3849..17ab29e799bbd 100644 --- a/tests/ui/fmt/respanned-literal-issue-106191.stderr +++ b/tests/ui/fmt/respanned-literal-issue-106191.stderr @@ -1,16 +1,16 @@ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/respanned-literal-issue-106191.rs:6:65 | LL | format_string_proc_macro::respan_to_invalid_format_literal!("Β‘"); - | ^^^ expected `'}'` in format string + | ^^^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/respanned-literal-issue-106191.rs:8:18 | LL | format_args!(r#concat!("Β‘ {")); - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/macros/issue-51848.stderr b/tests/ui/macros/issue-51848.stderr index c25bedf37b753..30b64113d731e 100644 --- a/tests/ui/macros/issue-51848.stderr +++ b/tests/ui/macros/issue-51848.stderr @@ -1,8 +1,8 @@ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/issue-51848.rs:6:20 | LL | println!("{"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace ... diff --git a/tests/ui/use/unused-trait-with-method-err.rs b/tests/ui/use/unused-trait-with-method-err.rs new file mode 100644 index 0000000000000..37684e1bf81e9 --- /dev/null +++ b/tests/ui/use/unused-trait-with-method-err.rs @@ -0,0 +1,17 @@ +// Test that we don't issue an unused import warning when there's +// a method lookup error and that trait was possibly applicable. + +use foo::Bar; + +mod foo { + pub trait Bar { + fn uwu(&self) {} + } +} + +struct Foo; + +fn main() { + Foo.uwu(); + //~^ ERROR no method named `uwu` found for struct `Foo` in the current scope +} diff --git a/tests/ui/use/unused-trait-with-method-err.stderr b/tests/ui/use/unused-trait-with-method-err.stderr new file mode 100644 index 0000000000000..7ca4563673bb1 --- /dev/null +++ b/tests/ui/use/unused-trait-with-method-err.stderr @@ -0,0 +1,19 @@ +error[E0599]: no method named `uwu` found for struct `Foo` in the current scope + --> $DIR/unused-trait-with-method-err.rs:15:9 + | +LL | struct Foo; + | ---------- method `uwu` not found for this struct +... +LL | Foo.uwu(); + | ^^^ method not found in `Foo` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Bar` defines an item `uwu`, perhaps you need to implement it + --> $DIR/unused-trait-with-method-err.rs:7:5 + | +LL | pub trait Bar { + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`.