Auto merge of #131723 - matthiaskrgr:rollup-krcslig, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #122670 (Fix bug where `option_env!` would return `None` when env var is present but not valid Unicode) - #131095 (Use environment variables instead of command line arguments for merged doctests) - #131339 (Expand set_ptr_value / with_metadata_of docs) - #131652 (Move polarity into `PolyTraitRef` rather than storing it on the side) - #131675 (Update lint message for ABI not supported) - #131681 (Fix up-to-date checking for run-make tests) - #131702 (Suppress import errors for traits that couldve applied for method lookup error) - #131703 (Resolved python deprecation warning in publish_toolstate.py) - #131710 (Remove `'apostrophes'` from `rustc_parse_format`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f79fae3069
93 changed files with 558 additions and 420 deletions
|
@ -308,7 +308,7 @@ impl TraitBoundModifiers {
|
||||||
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum GenericBound {
|
pub enum GenericBound {
|
||||||
Trait(PolyTraitRef, TraitBoundModifiers),
|
Trait(PolyTraitRef),
|
||||||
Outlives(Lifetime),
|
Outlives(Lifetime),
|
||||||
/// Precise capturing syntax: `impl Sized + use<'a>`
|
/// Precise capturing syntax: `impl Sized + use<'a>`
|
||||||
Use(ThinVec<PreciseCapturingArg>, Span),
|
Use(ThinVec<PreciseCapturingArg>, Span),
|
||||||
|
@ -1213,10 +1213,12 @@ impl Expr {
|
||||||
|
|
||||||
pub fn to_bound(&self) -> Option<GenericBound> {
|
pub fn to_bound(&self) -> Option<GenericBound> {
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
ExprKind::Path(None, path) => Some(GenericBound::Trait(
|
ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
|
||||||
PolyTraitRef::new(ThinVec::new(), path.clone(), self.span),
|
ThinVec::new(),
|
||||||
|
path.clone(),
|
||||||
TraitBoundModifiers::NONE,
|
TraitBoundModifiers::NONE,
|
||||||
)),
|
self.span,
|
||||||
|
))),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2972,6 +2974,9 @@ pub struct PolyTraitRef {
|
||||||
/// The `'a` in `for<'a> Foo<&'a T>`.
|
/// The `'a` in `for<'a> Foo<&'a T>`.
|
||||||
pub bound_generic_params: ThinVec<GenericParam>,
|
pub bound_generic_params: ThinVec<GenericParam>,
|
||||||
|
|
||||||
|
// Optional constness, asyncness, or polarity.
|
||||||
|
pub modifiers: TraitBoundModifiers,
|
||||||
|
|
||||||
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
|
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
|
||||||
pub trait_ref: TraitRef,
|
pub trait_ref: TraitRef,
|
||||||
|
|
||||||
|
@ -2979,9 +2984,15 @@ pub struct PolyTraitRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PolyTraitRef {
|
impl PolyTraitRef {
|
||||||
pub fn new(generic_params: ThinVec<GenericParam>, path: Path, span: Span) -> Self {
|
pub fn new(
|
||||||
|
generic_params: ThinVec<GenericParam>,
|
||||||
|
path: Path,
|
||||||
|
modifiers: TraitBoundModifiers,
|
||||||
|
span: Span,
|
||||||
|
) -> Self {
|
||||||
PolyTraitRef {
|
PolyTraitRef {
|
||||||
bound_generic_params: generic_params,
|
bound_generic_params: generic_params,
|
||||||
|
modifiers,
|
||||||
trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
|
trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
|
|
|
@ -913,7 +913,7 @@ fn walk_fn_ret_ty<T: MutVisitor>(vis: &mut T, fn_ret_ty: &mut FnRetTy) {
|
||||||
|
|
||||||
fn walk_param_bound<T: MutVisitor>(vis: &mut T, pb: &mut GenericBound) {
|
fn walk_param_bound<T: MutVisitor>(vis: &mut T, pb: &mut GenericBound) {
|
||||||
match pb {
|
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::Outlives(lifetime) => walk_lifetime(vis, lifetime),
|
||||||
GenericBound::Use(args, span) => {
|
GenericBound::Use(args, span) => {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
|
@ -1034,7 +1034,7 @@ fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut Tr
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
|
fn walk_poly_trait_ref<T: MutVisitor>(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));
|
bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
|
||||||
vis.visit_trait_ref(trait_ref);
|
vis.visit_trait_ref(trait_ref);
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
|
|
|
@ -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) => {
|
ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds) => {
|
||||||
match bounds.last() {
|
match bounds.last() {
|
||||||
Some(ast::GenericBound::Trait(bound, _)) => {
|
Some(ast::GenericBound::Trait(bound)) => {
|
||||||
match path_return_type(&bound.trait_ref.path) {
|
match path_return_type(&bound.trait_ref.path) {
|
||||||
Some(trailing_ty) => ty = trailing_ty,
|
Some(trailing_ty) => ty = trailing_ty,
|
||||||
None => break None,
|
None => break None,
|
||||||
|
|
|
@ -329,7 +329,7 @@ pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef)
|
||||||
where
|
where
|
||||||
V: Visitor<'a>,
|
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);
|
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
||||||
visitor.visit_trait_ref(trait_ref)
|
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 {
|
pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result {
|
||||||
match bound {
|
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::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
|
||||||
GenericBound::Use(args, _span) => {
|
GenericBound::Use(args, _span) => {
|
||||||
walk_list!(visitor, visit_precise_capturing_arg, args);
|
walk_list!(visitor, visit_precise_capturing_arg, args);
|
||||||
|
|
|
@ -1504,8 +1504,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
for bound in &bound_pred.bounds {
|
for bound in &bound_pred.bounds {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
*bound,
|
*bound,
|
||||||
GenericBound::Trait(_, TraitBoundModifiers {
|
GenericBound::Trait(PolyTraitRef {
|
||||||
polarity: BoundPolarity::Maybe(_),
|
modifiers: TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. },
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1224,13 +1224,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let bound = this.lower_poly_trait_ref(
|
let bound = this.lower_poly_trait_ref(
|
||||||
&PolyTraitRef {
|
&PolyTraitRef {
|
||||||
bound_generic_params: ThinVec::new(),
|
bound_generic_params: ThinVec::new(),
|
||||||
|
modifiers: TraitBoundModifiers::NONE,
|
||||||
trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
|
trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
|
||||||
span: t.span,
|
span: t.span,
|
||||||
},
|
},
|
||||||
itctx,
|
itctx,
|
||||||
TraitBoundModifiers::NONE,
|
|
||||||
);
|
);
|
||||||
let bound = (bound, hir::TraitBoundModifier::None);
|
|
||||||
let bounds = this.arena.alloc_from_iter([bound]);
|
let bounds = this.arena.alloc_from_iter([bound]);
|
||||||
let lifetime_bound = this.elided_dyn_bound(t.span);
|
let lifetime_bound = this.elided_dyn_bound(t.span);
|
||||||
(bounds, lifetime_bound)
|
(bounds, lifetime_bound)
|
||||||
|
@ -1357,10 +1356,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// We can safely ignore constness here since AST validation
|
// We can safely ignore constness here since AST validation
|
||||||
// takes care of rejecting invalid modifier combinations and
|
// takes care of rejecting invalid modifier combinations and
|
||||||
// const trait bounds in trait object types.
|
// const trait bounds in trait object types.
|
||||||
GenericBound::Trait(ty, modifiers) => {
|
GenericBound::Trait(ty) => {
|
||||||
let trait_ref = this.lower_poly_trait_ref(ty, itctx, *modifiers);
|
let trait_ref = this.lower_poly_trait_ref(ty, itctx);
|
||||||
let polarity = this.lower_trait_bound_modifiers(*modifiers);
|
Some(trait_ref)
|
||||||
Some((trait_ref, polarity))
|
|
||||||
}
|
}
|
||||||
GenericBound::Outlives(lifetime) => {
|
GenericBound::Outlives(lifetime) => {
|
||||||
if lifetime_bound.is_none() {
|
if lifetime_bound.is_none() {
|
||||||
|
@ -1993,21 +1991,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
span_ext: DUMMY_SP,
|
span_ext: DUMMY_SP,
|
||||||
});
|
});
|
||||||
|
|
||||||
hir::GenericBound::Trait(
|
hir::GenericBound::Trait(hir::PolyTraitRef {
|
||||||
hir::PolyTraitRef {
|
|
||||||
bound_generic_params: &[],
|
bound_generic_params: &[],
|
||||||
|
modifiers: hir::TraitBoundModifier::None,
|
||||||
trait_ref: hir::TraitRef {
|
trait_ref: hir::TraitRef {
|
||||||
path: self.make_lang_item_path(
|
path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
|
||||||
trait_lang_item,
|
|
||||||
opaque_ty_span,
|
|
||||||
Some(bound_args),
|
|
||||||
),
|
|
||||||
hir_ref_id: self.next_id(),
|
hir_ref_id: self.next_id(),
|
||||||
},
|
},
|
||||||
span: opaque_ty_span,
|
span: opaque_ty_span,
|
||||||
},
|
})
|
||||||
hir::TraitBoundModifier::None,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self))]
|
#[instrument(level = "trace", skip(self))]
|
||||||
|
@ -2017,10 +2009,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
itctx: ImplTraitContext,
|
itctx: ImplTraitContext,
|
||||||
) -> hir::GenericBound<'hir> {
|
) -> hir::GenericBound<'hir> {
|
||||||
match tpb {
|
match tpb {
|
||||||
GenericBound::Trait(p, modifiers) => hir::GenericBound::Trait(
|
GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
|
||||||
self.lower_poly_trait_ref(p, itctx, *modifiers),
|
|
||||||
self.lower_trait_bound_modifiers(*modifiers),
|
|
||||||
),
|
|
||||||
GenericBound::Outlives(lifetime) => {
|
GenericBound::Outlives(lifetime) => {
|
||||||
hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
|
hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
|
||||||
}
|
}
|
||||||
|
@ -2224,12 +2213,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
&mut self,
|
&mut self,
|
||||||
p: &PolyTraitRef,
|
p: &PolyTraitRef,
|
||||||
itctx: ImplTraitContext,
|
itctx: ImplTraitContext,
|
||||||
modifiers: ast::TraitBoundModifiers,
|
|
||||||
) -> hir::PolyTraitRef<'hir> {
|
) -> hir::PolyTraitRef<'hir> {
|
||||||
let bound_generic_params =
|
let bound_generic_params =
|
||||||
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.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);
|
let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
|
||||||
hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
|
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> {
|
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, _) => {
|
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
|
||||||
let principal = hir::PolyTraitRef {
|
let principal = hir::PolyTraitRef {
|
||||||
bound_generic_params: &[],
|
bound_generic_params: &[],
|
||||||
|
modifiers: hir::TraitBoundModifier::None,
|
||||||
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
|
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
|
||||||
span: self.lower_span(span),
|
span: self.lower_span(span),
|
||||||
};
|
};
|
||||||
let principal = (principal, hir::TraitBoundModifier::None);
|
|
||||||
|
|
||||||
// The original ID is taken by the `PolyTraitRef`,
|
// The original ID is taken by the `PolyTraitRef`,
|
||||||
// so the `Ty` itself needs a different one.
|
// so the `Ty` itself needs a different one.
|
||||||
|
|
|
@ -1263,7 +1263,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
if !bound_pred.bound_generic_params.is_empty() {
|
if !bound_pred.bound_generic_params.is_empty() {
|
||||||
for bound in &bound_pred.bounds {
|
for bound in &bound_pred.bounds {
|
||||||
match bound {
|
match bound {
|
||||||
GenericBound::Trait(t, _) => {
|
GenericBound::Trait(t) => {
|
||||||
if !t.bound_generic_params.is_empty() {
|
if !t.bound_generic_params.is_empty() {
|
||||||
self.dcx()
|
self.dcx()
|
||||||
.emit_err(errors::NestedLifetimes { span: t.span });
|
.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) {
|
fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
|
||||||
match bound {
|
match bound {
|
||||||
GenericBound::Trait(trait_ref, modifiers) => {
|
GenericBound::Trait(trait_ref) => {
|
||||||
match (ctxt, modifiers.constness, modifiers.polarity) {
|
match (ctxt, trait_ref.modifiers.constness, trait_ref.modifiers.polarity) {
|
||||||
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_))
|
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_))
|
||||||
if !self.features.more_maybe_bounds =>
|
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
|
// 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()
|
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
||||||
{
|
{
|
||||||
match segment.args.as_deref() {
|
match segment.args.as_deref() {
|
||||||
|
@ -1672,7 +1672,9 @@ fn deny_equality_constraints(
|
||||||
}),
|
}),
|
||||||
) {
|
) {
|
||||||
for bound in bounds {
|
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]
|
if full_path.segments[..full_path.segments.len() - 1]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|segment| segment.ident.name)
|
.map(|segment| segment.ident.name)
|
||||||
|
@ -1700,7 +1702,9 @@ fn deny_equality_constraints(
|
||||||
) {
|
) {
|
||||||
if ident == potential_param.ident {
|
if ident == potential_param.ident {
|
||||||
for bound in bounds {
|
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);
|
suggest(poly, potential_assoc, predicate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ mod item;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use ast::TraitBoundModifiers;
|
|
||||||
use rustc_ast::attr::AttrIdGenerator;
|
use rustc_ast::attr::AttrIdGenerator;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{
|
use rustc_ast::token::{
|
||||||
|
@ -1259,6 +1258,27 @@ impl<'a> State<'a> {
|
||||||
|
|
||||||
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
|
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
|
||||||
self.print_formal_generic_params(&t.bound_generic_params);
|
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)
|
self.print_trait_ref(&t.trait_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1746,31 +1766,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match bound {
|
match bound {
|
||||||
GenericBound::Trait(
|
GenericBound::Trait(tref) => {
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.print_poly_trait_ref(tref);
|
self.print_poly_trait_ref(tref);
|
||||||
}
|
}
|
||||||
GenericBound::Outlives(lt) => self.print_lifetime(*lt),
|
GenericBound::Outlives(lt) => self.print_lifetime(*lt),
|
||||||
|
|
|
@ -254,7 +254,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
debug!(?hrtb_bounds);
|
debug!(?hrtb_bounds);
|
||||||
|
|
||||||
hrtb_bounds.iter().for_each(|bound| {
|
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;
|
return;
|
||||||
};
|
};
|
||||||
diag.span_note(*trait_span, fluent::borrowck_limitations_implies_static);
|
diag.span_note(*trait_span, fluent::borrowck_limitations_implies_static);
|
||||||
|
@ -277,7 +277,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
bounds.iter().for_each(|bd| {
|
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
|
&& let Def(_, res_defid) = tr_ref.path.res
|
||||||
&& res_defid == trait_res_defid // trait id matches
|
&& res_defid == trait_res_defid // trait id matches
|
||||||
&& let TyKind::Path(Resolved(_, path)) = bounded_ty.kind
|
&& let TyKind::Path(Resolved(_, path)) = bounded_ty.kind
|
||||||
|
|
|
@ -837,7 +837,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
hir_ty
|
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(segment) = trait_ref.trait_ref.path.segments.last()
|
||||||
&& let Some(args) = segment.args
|
&& let Some(args) = segment.args
|
||||||
&& let [constraint] = args.constraints
|
&& let [constraint] = args.constraints
|
||||||
|
|
|
@ -333,12 +333,12 @@ fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee:
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_maybe_sized_bound(bound: &GenericBound) -> bool {
|
fn is_maybe_sized_bound(bound: &GenericBound) -> bool {
|
||||||
if let GenericBound::Trait(
|
if let GenericBound::Trait(trait_ref) = bound
|
||||||
trait_ref,
|
&& let TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. } =
|
||||||
TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. },
|
trait_ref.modifiers
|
||||||
) = bound
|
&& is_sized_marker(&trait_ref.trait_ref.path)
|
||||||
{
|
{
|
||||||
is_sized_marker(&trait_ref.trait_ref.path)
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use rustc_span::symbol::{Ident, Symbol, kw, sym};
|
||||||
use thin_vec::thin_vec;
|
use thin_vec::thin_vec;
|
||||||
|
|
||||||
use crate::errors;
|
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<Symbol, VarError> {
|
fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result<Symbol, VarError> {
|
||||||
let var = var.as_str();
|
let var = var.as_str();
|
||||||
|
@ -32,19 +32,28 @@ pub(crate) fn expand_option_env<'cx>(
|
||||||
sp: Span,
|
sp: Span,
|
||||||
tts: TokenStream,
|
tts: TokenStream,
|
||||||
) -> MacroExpanderResult<'cx> {
|
) -> 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(());
|
return ExpandResult::Retry(());
|
||||||
};
|
};
|
||||||
let var = match mac {
|
let var = match mac {
|
||||||
Ok(var) => var,
|
Ok((var, _)) => var,
|
||||||
Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
|
Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let sp = cx.with_def_site_ctxt(sp);
|
let sp = cx.with_def_site_ctxt(sp);
|
||||||
let value = lookup_env(cx, var).ok();
|
let value = lookup_env(cx, var);
|
||||||
cx.sess.psess.env_depinfo.borrow_mut().insert((var, value));
|
cx.sess.psess.env_depinfo.borrow_mut().insert((var, value.as_ref().ok().copied()));
|
||||||
let e = match value {
|
let e = match value {
|
||||||
None => {
|
Err(VarError::NotPresent) => {
|
||||||
let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp));
|
let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp));
|
||||||
cx.expr_path(cx.path_all(
|
cx.expr_path(cx.path_all(
|
||||||
sp,
|
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_call_global(sp, cx.std_path(&[sym::option, sym::Option, sym::Some]), thin_vec![
|
||||||
cx.expr_str(sp, value)
|
cx.expr_str(sp, value)
|
||||||
])
|
])
|
||||||
|
|
|
@ -171,6 +171,30 @@ pub(crate) fn get_single_str_spanned_from_tts(
|
||||||
tts: TokenStream,
|
tts: TokenStream,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> ExpandResult<Result<(Symbol, Span), ErrorGuaranteed>, ()> {
|
) -> ExpandResult<Result<(Symbol, Span), ErrorGuaranteed>, ()> {
|
||||||
|
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<Result<P<ast::Expr>, ErrorGuaranteed>, ()> {
|
||||||
let mut p = cx.new_parser_from_tts(tts);
|
let mut p = cx.new_parser_from_tts(tts);
|
||||||
if p.token == token::Eof {
|
if p.token == token::Eof {
|
||||||
let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
|
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 {
|
if p.token != token::Eof {
|
||||||
cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
|
cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
|
||||||
}
|
}
|
||||||
expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| {
|
ExpandResult::Ready(Ok(ret))
|
||||||
res.map_err(|err| match err {
|
|
||||||
Ok((err, _)) => err.emit(),
|
|
||||||
Err(guar) => guar,
|
|
||||||
})
|
|
||||||
.map(|(symbol, _style, span)| (symbol, span))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts comma-separated expressions from `tts`.
|
/// Extracts comma-separated expressions from `tts`.
|
||||||
|
|
|
@ -143,16 +143,10 @@ impl<'a> ExtCtxt<'a> {
|
||||||
ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID }
|
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 {
|
ast::PolyTraitRef {
|
||||||
bound_generic_params: ThinVec::new(),
|
bound_generic_params: ThinVec::new(),
|
||||||
trait_ref: self.trait_ref(path),
|
modifiers: ast::TraitBoundModifiers {
|
||||||
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,
|
polarity: ast::BoundPolarity::Positive,
|
||||||
constness: if is_const {
|
constness: if is_const {
|
||||||
ast::BoundConstness::Maybe(DUMMY_SP)
|
ast::BoundConstness::Maybe(DUMMY_SP)
|
||||||
|
@ -160,7 +154,14 @@ impl<'a> ExtCtxt<'a> {
|
||||||
ast::BoundConstness::Never
|
ast::BoundConstness::Never
|
||||||
},
|
},
|
||||||
asyncness: ast::BoundAsyncness::Normal,
|
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, is_const))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime {
|
pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime {
|
||||||
|
|
|
@ -519,7 +519,7 @@ pub enum TraitBoundModifier {
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||||
pub enum GenericBound<'hir> {
|
pub enum GenericBound<'hir> {
|
||||||
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
|
Trait(PolyTraitRef<'hir>),
|
||||||
Outlives(&'hir Lifetime),
|
Outlives(&'hir Lifetime),
|
||||||
Use(&'hir [PreciseCapturingArg<'hir>], Span),
|
Use(&'hir [PreciseCapturingArg<'hir>], Span),
|
||||||
}
|
}
|
||||||
|
@ -527,7 +527,7 @@ pub enum GenericBound<'hir> {
|
||||||
impl GenericBound<'_> {
|
impl GenericBound<'_> {
|
||||||
pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
|
pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
|
||||||
match self {
|
match self {
|
||||||
GenericBound::Trait(data, _) => Some(&data.trait_ref),
|
GenericBound::Trait(data) => Some(&data.trait_ref),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2873,11 +2873,7 @@ pub enum TyKind<'hir> {
|
||||||
OpaqueDef(&'hir OpaqueTy<'hir>, &'hir [GenericArg<'hir>]),
|
OpaqueDef(&'hir OpaqueTy<'hir>, &'hir [GenericArg<'hir>]),
|
||||||
/// A trait object type `Bound1 + Bound2 + Bound3`
|
/// A trait object type `Bound1 + Bound2 + Bound3`
|
||||||
/// where `Bound` is a trait or a lifetime.
|
/// where `Bound` is a trait or a lifetime.
|
||||||
TraitObject(
|
TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
|
||||||
&'hir [(PolyTraitRef<'hir>, TraitBoundModifier)],
|
|
||||||
&'hir Lifetime,
|
|
||||||
TraitObjectSyntax,
|
|
||||||
),
|
|
||||||
/// Unused for now.
|
/// Unused for now.
|
||||||
Typeof(&'hir AnonConst),
|
Typeof(&'hir AnonConst),
|
||||||
/// `TyKind::Infer` means the type should be inferred instead of it having been
|
/// `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>`.
|
/// The `'a` in `for<'a> Foo<&'a T>`.
|
||||||
pub bound_generic_params: &'hir [GenericParam<'hir>],
|
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>`.
|
/// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`.
|
||||||
pub trait_ref: TraitRef<'hir>,
|
pub trait_ref: TraitRef<'hir>,
|
||||||
|
|
||||||
|
|
|
@ -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));
|
try_visit!(visitor.visit_array_length(length));
|
||||||
}
|
}
|
||||||
TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
|
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_poly_trait_ref(bound));
|
||||||
}
|
}
|
||||||
try_visit!(visitor.visit_lifetime(lifetime));
|
try_visit!(visitor.visit_lifetime(lifetime));
|
||||||
|
@ -1160,7 +1160,7 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(
|
||||||
bound: &'v GenericBound<'v>,
|
bound: &'v GenericBound<'v>,
|
||||||
) -> V::Result {
|
) -> V::Result {
|
||||||
match *bound {
|
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::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
|
||||||
GenericBound::Use(args, _) => {
|
GenericBound::Use(args, _) => {
|
||||||
walk_list!(visitor, visit_precise_capturing_arg, args);
|
walk_list!(visitor, visit_precise_capturing_arg, args);
|
||||||
|
|
|
@ -61,9 +61,9 @@ pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab
|
||||||
Some(true) => (),
|
Some(true) => (),
|
||||||
Some(false) | None => {
|
Some(false) | None => {
|
||||||
tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
|
tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
|
||||||
lint.primary_message(
|
lint.primary_message(format!(
|
||||||
"use of calling convention not supported on this target on function pointer",
|
"the calling convention {abi} is not supported on this target"
|
||||||
);
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -829,7 +829,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
|
||||||
|
|
||||||
fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
|
fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
|
||||||
match ty.kind {
|
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()),
|
[s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()),
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
|
|
@ -866,7 +866,7 @@ impl<'tcx> ItemCtxt<'tcx> {
|
||||||
#[instrument(level = "trace", skip(self))]
|
#[instrument(level = "trace", skip(self))]
|
||||||
fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
|
fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
|
||||||
match b {
|
match b {
|
||||||
hir::GenericBound::Trait(poly_trait_ref, _) => {
|
hir::GenericBound::Trait(poly_trait_ref) => {
|
||||||
let trait_ref = &poly_trait_ref.trait_ref;
|
let trait_ref = &poly_trait_ref.trait_ref;
|
||||||
if let Some(trait_did) = trait_ref.trait_def_id() {
|
if let Some(trait_did) = trait_ref.trait_def_id() {
|
||||||
self.tcx.trait_may_define_assoc_item(trait_did, assoc_name)
|
self.tcx.trait_may_define_assoc_item(trait_did, assoc_name)
|
||||||
|
|
|
@ -644,7 +644,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
debug!(?bounds, ?lifetime, "TraitObject");
|
debug!(?bounds, ?lifetime, "TraitObject");
|
||||||
let scope = Scope::TraitRefBoundary { s: self.scope };
|
let scope = Scope::TraitRefBoundary { s: self.scope };
|
||||||
self.with(scope, |this| {
|
self.with(scope, |this| {
|
||||||
for (bound, _) in bounds {
|
for bound in bounds {
|
||||||
this.visit_poly_trait_ref_inner(
|
this.visit_poly_trait_ref_inner(
|
||||||
bound,
|
bound,
|
||||||
NonLifetimeBinderAllowed::Deny("trait object types"),
|
NonLifetimeBinderAllowed::Deny("trait object types"),
|
||||||
|
@ -1918,7 +1918,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
predicate.bounds.iter().find_map(|bound| {
|
predicate.bounds.iter().find_map(|bound| {
|
||||||
let hir::GenericBound::Trait(trait_, _) = bound else {
|
let hir::GenericBound::Trait(trait_) = bound else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
BoundVarContext::supertrait_hrtb_vars(
|
BoundVarContext::supertrait_hrtb_vars(
|
||||||
|
|
|
@ -44,10 +44,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
|
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
|
||||||
let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
||||||
for hir_bound in hir_bounds {
|
for hir_bound in hir_bounds {
|
||||||
let hir::GenericBound::Trait(ptr, modifier) = hir_bound else {
|
let hir::GenericBound::Trait(ptr) = hir_bound else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
match modifier {
|
match ptr.modifiers {
|
||||||
hir::TraitBoundModifier::Maybe => unbounds.push(ptr),
|
hir::TraitBoundModifier::Maybe => unbounds.push(ptr),
|
||||||
hir::TraitBoundModifier::Negative => {
|
hir::TraitBoundModifier::Negative => {
|
||||||
if let Some(sized_def_id) = sized_def_id
|
if let Some(sized_def_id) = sized_def_id
|
||||||
|
@ -156,8 +156,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
{
|
{
|
||||||
for hir_bound in hir_bounds {
|
for hir_bound in hir_bounds {
|
||||||
match hir_bound {
|
match hir_bound {
|
||||||
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
|
hir::GenericBound::Trait(poly_trait_ref) => {
|
||||||
let (constness, polarity) = match modifier {
|
let (constness, polarity) = match poly_trait_ref.modifiers {
|
||||||
hir::TraitBoundModifier::Const => {
|
hir::TraitBoundModifier::Const => {
|
||||||
(ty::BoundConstness::Const, ty::PredicatePolarity::Positive)
|
(ty::BoundConstness::Const, ty::PredicatePolarity::Positive)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: hir::HirId,
|
hir_id: hir::HirId,
|
||||||
hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)],
|
hir_trait_bounds: &[hir::PolyTraitRef<'tcx>],
|
||||||
lifetime: &hir::Lifetime,
|
lifetime: &hir::Lifetime,
|
||||||
representation: DynKind,
|
representation: DynKind,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
|
@ -39,8 +39,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
let mut potential_assoc_types = Vec::new();
|
let mut potential_assoc_types = Vec::new();
|
||||||
let dummy_self = self.tcx().types.trait_object_dummy_self;
|
let dummy_self = self.tcx().types.trait_object_dummy_self;
|
||||||
for (trait_bound, modifier) in hir_trait_bounds.iter().rev() {
|
for trait_bound in hir_trait_bounds.iter().rev() {
|
||||||
if *modifier == hir::TraitBoundModifier::Maybe {
|
// FIXME: This doesn't handle `? const`.
|
||||||
|
if trait_bound.modifiers == hir::TraitBoundModifier::Maybe {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let GenericArgCountResult {
|
if let GenericArgCountResult {
|
||||||
|
@ -263,7 +264,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let args = tcx.mk_args(&args);
|
let args = tcx.mk_args(&args);
|
||||||
|
|
||||||
let span = i.bottom().1;
|
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.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
|
||||||
&& hir_bound.span.contains(span)
|
&& hir_bound.span.contains(span)
|
||||||
});
|
});
|
||||||
|
|
|
@ -718,7 +718,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
&self,
|
&self,
|
||||||
associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
|
associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
|
||||||
potential_assoc_types: Vec<usize>,
|
potential_assoc_types: Vec<usize>,
|
||||||
trait_bounds: &[(hir::PolyTraitRef<'_>, hir::TraitBoundModifier)],
|
trait_bounds: &[hir::PolyTraitRef<'_>],
|
||||||
) {
|
) {
|
||||||
if associated_types.values().all(|v| v.is_empty()) {
|
if associated_types.values().all(|v| v.is_empty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -764,12 +764,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
// related to issue #91997, turbofishes added only when in an expr or pat
|
// related to issue #91997, turbofishes added only when in an expr or pat
|
||||||
let mut in_expr_or_pat = false;
|
let mut in_expr_or_pat = false;
|
||||||
if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
|
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 {
|
in_expr_or_pat = match grandparent {
|
||||||
hir::Node::Expr(_) | hir::Node::Pat(_) => true,
|
hir::Node::Expr(_) | hir::Node::Pat(_) => true,
|
||||||
_ => false,
|
_ => 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
|
// 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
|
// segments, even though `trait_ref.path.segments` is of length `1`. Work
|
||||||
// around that bug here, even though it should be fixed elsewhere.
|
// 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.
|
// and we can then use their span to indicate this to the user.
|
||||||
let bound_names = trait_bounds
|
let bound_names = trait_bounds
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(poly_trait_ref, _)| {
|
.filter_map(|poly_trait_ref| {
|
||||||
let path = poly_trait_ref.trait_ref.path.segments.last()?;
|
let path = poly_trait_ref.trait_ref.path.segments.last()?;
|
||||||
let args = path.args?;
|
let args = path.args?;
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
.ok()
|
.ok()
|
||||||
.is_some_and(|s| s.trim_end().ends_with('<'));
|
.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![(
|
let mut sugg = vec![(
|
||||||
self_ty.span.shrink_to_lo(),
|
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.
|
// Check if trait object is safe for suggesting dynamic dispatch.
|
||||||
let is_dyn_compatible = match self_ty.kind {
|
let is_dyn_compatible = match self_ty.kind {
|
||||||
hir::TyKind::TraitObject(objects, ..) => {
|
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),
|
Res::Def(DefKind::Trait, id) => tcx.is_dyn_compatible(id),
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
|
|
|
@ -301,16 +301,13 @@ impl<'a> State<'a> {
|
||||||
self.word_space("dyn");
|
self.word_space("dyn");
|
||||||
}
|
}
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for (bound, modifier) in bounds {
|
for bound in bounds {
|
||||||
if first {
|
if first {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
self.nbsp();
|
self.nbsp();
|
||||||
self.word_space("+");
|
self.word_space("+");
|
||||||
}
|
}
|
||||||
if *modifier == TraitBoundModifier::Maybe {
|
|
||||||
self.word("?");
|
|
||||||
}
|
|
||||||
self.print_poly_trait_ref(bound);
|
self.print_poly_trait_ref(bound);
|
||||||
}
|
}
|
||||||
if !lifetime.is_elided() {
|
if !lifetime.is_elided() {
|
||||||
|
@ -679,6 +676,10 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef<'_>) {
|
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_formal_generic_params(t.bound_generic_params);
|
||||||
self.print_trait_ref(&t.trait_ref);
|
self.print_trait_ref(&t.trait_ref);
|
||||||
}
|
}
|
||||||
|
@ -2077,10 +2078,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match bound {
|
match bound {
|
||||||
GenericBound::Trait(tref, modifier) => {
|
GenericBound::Trait(tref) => {
|
||||||
if modifier == &TraitBoundModifier::Maybe {
|
|
||||||
self.word("?");
|
|
||||||
}
|
|
||||||
self.print_poly_trait_ref(tref);
|
self.print_poly_trait_ref(tref);
|
||||||
}
|
}
|
||||||
GenericBound::Outlives(lt) => {
|
GenericBound::Outlives(lt) => {
|
||||||
|
|
|
@ -849,7 +849,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
hir::FnRetTy::Return(hir_ty) => {
|
hir::FnRetTy::Return(hir_ty) => {
|
||||||
if let hir::TyKind::OpaqueDef(op_ty, ..) = hir_ty.kind
|
if let hir::TyKind::OpaqueDef(op_ty, ..) = hir_ty.kind
|
||||||
// FIXME: account for RPITIT.
|
// 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), .. }) =
|
&& let Some(hir::PathSegment { args: Some(generic_args), .. }) =
|
||||||
trait_ref.trait_ref.path.segments.last()
|
trait_ref.trait_ref.path.segments.last()
|
||||||
&& let [constraint] = generic_args.constraints
|
&& 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
|
// extract all bounds from the source code using their spans
|
||||||
let all_matching_bounds_strs = predicates_from_where
|
let all_matching_bounds_strs = predicates_from_where
|
||||||
.filter_map(|bound| match bound {
|
.filter_map(|bound| match bound {
|
||||||
GenericBound::Trait(_, _) => {
|
GenericBound::Trait(_) => {
|
||||||
self.tcx.sess.source_map().span_to_snippet(bound.span()).ok()
|
self.tcx.sess.source_map().span_to_snippet(bound.span()).ok()
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
|
@ -199,6 +199,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self_ty, segment, span, call_expr, self_expr, &pick, args,
|
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 {
|
for &import_id in &pick.import_ids {
|
||||||
debug!("used_trait_import: {:?}", import_id);
|
debug!("used_trait_import: {:?}", import_id);
|
||||||
self.typeck_results.borrow_mut().used_trait_imports.insert(import_id);
|
self.typeck_results.borrow_mut().used_trait_imports.insert(import_id);
|
||||||
|
|
|
@ -191,6 +191,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
trait_missing_method: bool,
|
trait_missing_method: bool,
|
||||||
) -> ErrorGuaranteed {
|
) -> 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) {
|
let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
|
||||||
hir::Node::Expr(&hir::Expr {
|
hir::Node::Expr(&hir::Expr {
|
||||||
kind: hir::ExprKind::MethodCall(segment, rcvr, args, _),
|
kind: hir::ExprKind::MethodCall(segment, rcvr, args, _),
|
||||||
|
|
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
syn = { version = "2.0.9", features = ["full"] }
|
syn = { version = "2.0.9", features = ["full", "extra-traits"] }
|
||||||
proc-macro2 = "1"
|
proc-macro2 = "1"
|
||||||
quote = "1"
|
quote = "1"
|
||||||
|
|
||||||
|
|
|
@ -112,10 +112,11 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
|
||||||
|
|
||||||
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
|
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
|
||||||
let hir::TyKind::TraitObject(bounds, _lifetime, _syntax) = &ty.kind else { return };
|
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();
|
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))
|
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 };
|
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 });
|
cx.emit_span_lint(DYN_DROP, bound.span, DropGlue { tcx: cx.tcx, def_id });
|
||||||
|
|
|
@ -3859,7 +3859,7 @@ declare_lint! {
|
||||||
/// This will produce:
|
/// This will produce:
|
||||||
///
|
///
|
||||||
/// ```text
|
/// ```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
|
/// --> $DIR/unsupported.rs:34:15
|
||||||
/// |
|
/// |
|
||||||
/// LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
/// LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
||||||
|
|
|
@ -192,7 +192,8 @@ fn suggest_changing_unsized_bound(
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_, bound)| {
|
.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
|
&& poly.trait_ref.trait_def_id() == def_id
|
||||||
{
|
{
|
||||||
true
|
true
|
||||||
|
|
|
@ -2113,7 +2113,7 @@ impl<'a> Parser<'a> {
|
||||||
&& let Some(poly) = bounds
|
&& let Some(poly) = bounds
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|bound| match bound {
|
.filter_map(|bound| match bound {
|
||||||
ast::GenericBound::Trait(poly, _) => Some(poly),
|
ast::GenericBound::Trait(poly) => Some(poly),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.last()
|
.last()
|
||||||
|
|
|
@ -948,8 +948,8 @@ impl<'a> Parser<'a> {
|
||||||
{
|
{
|
||||||
return Ok((false, seg.ident, seg.args.as_deref().cloned()));
|
return Ok((false, seg.ident, seg.args.as_deref().cloned()));
|
||||||
} else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind
|
} else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind
|
||||||
&& let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE)] =
|
&& let [ast::GenericBound::Trait(trait_ref)] = bounds.as_slice()
|
||||||
bounds.as_slice()
|
&& trait_ref.modifiers == ast::TraitBoundModifiers::NONE
|
||||||
&& let [seg] = trait_ref.trait_ref.path.segments.as_slice()
|
&& let [seg] = trait_ref.trait_ref.path.segments.as_slice()
|
||||||
{
|
{
|
||||||
return Ok((true, seg.ident, seg.args.as_deref().cloned()));
|
return Ok((true, seg.ident, seg.args.as_deref().cloned()));
|
||||||
|
|
|
@ -420,8 +420,13 @@ impl<'a> Parser<'a> {
|
||||||
lo: Span,
|
lo: Span,
|
||||||
parse_plus: bool,
|
parse_plus: bool,
|
||||||
) -> PResult<'a, TyKind> {
|
) -> PResult<'a, TyKind> {
|
||||||
let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span));
|
let poly_trait_ref = PolyTraitRef::new(
|
||||||
let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifiers::NONE)];
|
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)
|
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));
|
let poly_trait =
|
||||||
Ok(GenericBound::Trait(poly_trait, modifiers))
|
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(..)`
|
// recovers a `Fn(..)` parenthesized-style path from `fn(..)`
|
||||||
|
|
|
@ -473,19 +473,19 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = peek_pos;
|
pos = peek_pos;
|
||||||
description = format!("expected `'}}'`, found `{maybe:?}`");
|
description = format!("expected `}}`, found `{}`", maybe.escape_debug());
|
||||||
} else {
|
} else {
|
||||||
description = "expected `'}'` but string was terminated".to_owned();
|
description = "expected `}` but string was terminated".to_owned();
|
||||||
// point at closing `"`
|
// point at closing `"`
|
||||||
pos = self.input.len() - if self.append_newline { 1 } else { 0 };
|
pos = self.input.len() - if self.append_newline { 1 } else { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
let pos = self.to_span_index(pos);
|
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('}') {
|
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)),
|
arg.format.fill_span.map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -519,11 +519,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE) = bound
|
let ast::GenericBound::Trait(trait_ref) = bound else {
|
||||||
else {
|
|
||||||
continue;
|
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(
|
err.span_suggestion_verbose(
|
||||||
constraint.ident.span.between(trait_ref.span),
|
constraint.ident.span.between(trait_ref.span),
|
||||||
"you might have meant to write a path instead of an associated type bound",
|
"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 {
|
if bounds.iter().all(|bound| match bound {
|
||||||
ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true,
|
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![];
|
let mut sugg = vec![];
|
||||||
if base_error.span != start_span {
|
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| {
|
let param = generics.params.iter().find_map(|param| {
|
||||||
// Only consider type params with exactly one trait bound.
|
// Only consider type params with exactly one trait bound.
|
||||||
if let [bound] = &*param.bounds
|
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
|
&& tref.span == span
|
||||||
&& param.ident.span.eq_ctxt(span)
|
&& param.ident.span.eq_ctxt(span)
|
||||||
{
|
{
|
||||||
|
@ -1333,8 +1335,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
}
|
}
|
||||||
if let (
|
if let (
|
||||||
[ast::PathSegment { args: None, .. }],
|
[ast::PathSegment { args: None, .. }],
|
||||||
[ast::GenericBound::Trait(poly_trait_ref, ast::TraitBoundModifiers::NONE)],
|
[ast::GenericBound::Trait(poly_trait_ref)],
|
||||||
) = (&type_param_path.segments[..], &bounds[..])
|
) = (&type_param_path.segments[..], &bounds[..])
|
||||||
|
&& poly_trait_ref.modifiers == ast::TraitBoundModifiers::NONE
|
||||||
{
|
{
|
||||||
if let [ast::PathSegment { ident, args: None, .. }] =
|
if let [ast::PathSegment { ident, args: None, .. }] =
|
||||||
&poly_trait_ref.trait_ref.path.segments[..]
|
&poly_trait_ref.trait_ref.path.segments[..]
|
||||||
|
@ -2814,7 +2817,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
&& bounded_ty.id == binder
|
&& bounded_ty.id == binder
|
||||||
{
|
{
|
||||||
for bound in bounds {
|
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
|
&& let span = poly_trait_ref
|
||||||
.span
|
.span
|
||||||
.with_hi(poly_trait_ref.trait_ref.path.span.lo())
|
.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 =
|
let mut lt_finder =
|
||||||
LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] };
|
LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] };
|
||||||
for bound in arg_refs {
|
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);
|
lt_finder.visit_trait_ref(&trait_ref.trait_ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3444,17 +3447,15 @@ fn mk_where_bound_predicate(
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
bound_generic_params: ThinVec::new(),
|
bound_generic_params: ThinVec::new(),
|
||||||
bounded_ty: ast::ptr::P(ty.clone()),
|
bounded_ty: ast::ptr::P(ty.clone()),
|
||||||
bounds: vec![ast::GenericBound::Trait(
|
bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef {
|
||||||
ast::PolyTraitRef {
|
|
||||||
bound_generic_params: ThinVec::new(),
|
bound_generic_params: ThinVec::new(),
|
||||||
|
modifiers: ast::TraitBoundModifiers::NONE,
|
||||||
trait_ref: ast::TraitRef {
|
trait_ref: ast::TraitRef {
|
||||||
path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None },
|
path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None },
|
||||||
ref_id: DUMMY_NODE_ID,
|
ref_id: DUMMY_NODE_ID,
|
||||||
},
|
},
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
},
|
})],
|
||||||
ast::TraitBoundModifiers::NONE,
|
|
||||||
)],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(new_where_bound_predicate)
|
Some(new_where_bound_predicate)
|
||||||
|
|
|
@ -86,7 +86,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::TyKind::TraitObject(bounds, ..) => {
|
hir::TyKind::TraitObject(bounds, ..) => {
|
||||||
for (bound, _) in bounds {
|
for bound in bounds {
|
||||||
self.current_index.shift_in(1);
|
self.current_index.shift_in(1);
|
||||||
self.visit_poly_trait_ref(bound);
|
self.visit_poly_trait_ref(bound);
|
||||||
self.current_index.shift_out(1);
|
self.current_index.shift_out(1);
|
||||||
|
|
|
@ -599,7 +599,7 @@ impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
|
||||||
_,
|
_,
|
||||||
) = t.kind
|
) = t.kind
|
||||||
{
|
{
|
||||||
for (ptr, _) in poly_trait_refs {
|
for ptr in poly_trait_refs {
|
||||||
if Some(self.1) == ptr.trait_ref.trait_def_id() {
|
if Some(self.1) == ptr.trait_ref.trait_def_id() {
|
||||||
self.0.push(ptr.span);
|
self.0.push(ptr.span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
// FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting.
|
||||||
|
|
||||||
let trait_bounds = bounds.iter().filter_map(|bound| match bound {
|
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,
|
_ => None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -740,9 +740,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match (
|
) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match (
|
||||||
left, right,
|
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()
|
if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
|
||||||
&& ml == mr =>
|
&& tl.modifiers == tr.modifiers =>
|
||||||
{
|
{
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
|
@ -439,7 +439,7 @@ pub fn report_dyn_incompatibility<'tcx>(
|
||||||
if tcx.parent_hir_node(hir_id).fn_sig().is_some() {
|
if tcx.parent_hir_node(hir_id).fn_sig().is_some() {
|
||||||
// Do not suggest `impl Trait` when dealing with things like super-traits.
|
// Do not suggest `impl Trait` when dealing with things like super-traits.
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
ty.span.until(trait_ref.0.span),
|
ty.span.until(trait_ref.span),
|
||||||
"consider using an opaque type instead",
|
"consider using an opaque type instead",
|
||||||
"impl ",
|
"impl ",
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
|
|
|
@ -3074,11 +3074,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
hir::TyKind::TraitObject(traits, _, _) => {
|
hir::TyKind::TraitObject(traits, _, _) => {
|
||||||
let (span, kw) = match 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.
|
// Missing `dyn` in front of trait object.
|
||||||
(ty.span.shrink_to_lo(), "dyn ")
|
(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:?}"),
|
[] => span_bug!(ty.span, "trait object with no traits: {ty:?}"),
|
||||||
};
|
};
|
||||||
let needs_parens = traits.len() != 1;
|
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 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 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.
|
// `async fn` should always lower to a single bound... but don't ICE.
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
|
@ -125,7 +125,7 @@ fn sized_trait_bound_spans<'tcx>(
|
||||||
bounds: hir::GenericBounds<'tcx>,
|
bounds: hir::GenericBounds<'tcx>,
|
||||||
) -> impl 'tcx + Iterator<Item = Span> {
|
) -> impl 'tcx + Iterator<Item = Span> {
|
||||||
bounds.iter().filter_map(move |b| match b {
|
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(
|
if trait_has_sized_self(
|
||||||
tcx,
|
tcx,
|
||||||
trait_ref.trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
|
trait_ref.trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
|
||||||
|
|
|
@ -1107,17 +1107,19 @@ pub(crate) mod builtin {
|
||||||
///
|
///
|
||||||
/// If the named environment variable is present at compile time, this will
|
/// If the named environment variable is present at compile time, this will
|
||||||
/// expand into an expression of type `Option<&'static str>` whose value is
|
/// expand into an expression of type `Option<&'static str>` whose value is
|
||||||
/// `Some` of the value of the environment variable. If the environment
|
/// `Some` of the value of the environment variable (a compilation error
|
||||||
/// variable is not present, then this will expand to `None`. See
|
/// will be emitted if the environment variable is not a valid Unicode
|
||||||
/// [`Option<T>`][Option] for more information on this type. Use
|
/// string). If the environment variable is not present, then this will
|
||||||
/// [`std::env::var`] instead if you want to read the value at runtime.
|
/// expand to `None`. See [`Option<T>`][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
|
/// [`std::env::var`]: ../std/env/fn.var.html
|
||||||
///
|
///
|
||||||
/// A compile time error is never emitted when using this macro regardless
|
/// A compile time error is only emitted when using this macro if the
|
||||||
/// of whether the environment variable is present or not.
|
/// environment variable exists and is not a valid Unicode string. To also
|
||||||
/// To emit a compile error if the environment variable is not present,
|
/// emit a compile error if the environment variable is not present, use the
|
||||||
/// use the [`env!`] macro instead.
|
/// [`env!`] macro instead.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -63,21 +63,22 @@ impl<T: ?Sized> *const T {
|
||||||
self as _
|
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
|
/// This operation will ignore the address part of its `meta` operand and discard existing
|
||||||
/// will ignore the pointer part, whereas for (thin) pointers to sized
|
/// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect
|
||||||
/// types, this has the same effect as a simple cast.
|
/// 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
|
/// The resulting pointer will have provenance of `self`. This operation is semantically the
|
||||||
/// pointer, this operation is semantically the same as creating a new
|
/// same as creating a new pointer with the data pointer value of `self` but the metadata of
|
||||||
/// fat pointer with the data pointer value of `self` but the metadata of
|
/// `meta`, being fat or thin depending on the `meta` operand.
|
||||||
/// `meta`.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// This function is primarily useful for allowing byte-wise pointer
|
/// This function is primarily useful for enabling pointer arithmetic on potentially fat
|
||||||
/// arithmetic on potentially fat pointers:
|
/// 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)]
|
/// #![feature(set_ptr_value)]
|
||||||
|
@ -91,6 +92,26 @@ impl<T: ?Sized> *const T {
|
||||||
/// println!("{:?}", &*ptr); // will print "3"
|
/// 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")]
|
#[unstable(feature = "set_ptr_value", issue = "75091")]
|
||||||
#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
|
#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[must_use = "returns a new pointer rather than modifying its argument"]
|
#[must_use = "returns a new pointer rather than modifying its argument"]
|
||||||
|
|
|
@ -45,21 +45,22 @@ impl<T: ?Sized> *mut T {
|
||||||
self as _
|
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
|
/// This operation will ignore the address part of its `meta` operand and discard existing
|
||||||
/// will ignore the pointer part, whereas for (thin) pointers to sized
|
/// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect
|
||||||
/// types, this has the same effect as a simple cast.
|
/// 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
|
/// The resulting pointer will have provenance of `self`. This operation is semantically the
|
||||||
/// pointer, this operation is semantically the same as creating a new
|
/// same as creating a new pointer with the data pointer value of `self` but the metadata of
|
||||||
/// fat pointer with the data pointer value of `self` but the metadata of
|
/// `meta`, being fat or thin depending on the `meta` operand.
|
||||||
/// `meta`.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// This function is primarily useful for allowing byte-wise pointer
|
/// This function is primarily useful for enabling pointer arithmetic on potentially fat
|
||||||
/// arithmetic on potentially fat pointers:
|
/// 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)]
|
/// #![feature(set_ptr_value)]
|
||||||
|
@ -73,6 +74,25 @@ impl<T: ?Sized> *mut T {
|
||||||
/// println!("{:?}", &*ptr); // will print "3"
|
/// 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")]
|
#[unstable(feature = "set_ptr_value", issue = "75091")]
|
||||||
#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
|
#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[must_use = "returns a new pointer rather than modifying its argument"]
|
#[must_use = "returns a new pointer rather than modifying its argument"]
|
||||||
|
|
|
@ -214,15 +214,15 @@ fn clean_generic_bound<'tcx>(
|
||||||
) -> Option<GenericBound> {
|
) -> Option<GenericBound> {
|
||||||
Some(match *bound {
|
Some(match *bound {
|
||||||
hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)),
|
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.
|
// `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())
|
&& cx.tcx.lang_items().destruct_trait() == Some(t.trait_ref.trait_def_id().unwrap())
|
||||||
{
|
{
|
||||||
return None;
|
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, ..) => {
|
hir::GenericBound::Use(args, ..) => {
|
||||||
GenericBound::Use(args.iter().map(|arg| arg.name()).collect())
|
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::Path(_) => clean_qpath(ty, cx),
|
||||||
TyKind::TraitObject(bounds, lifetime, _) => {
|
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 =
|
let lifetime =
|
||||||
if !lifetime.is_elided() { Some(clean_lifetime(lifetime, cx)) } else { None };
|
if !lifetime.is_elided() { Some(clean_lifetime(lifetime, cx)) } else { None };
|
||||||
DynTrait(bounds, lifetime)
|
DynTrait(bounds, lifetime)
|
||||||
|
|
|
@ -643,8 +643,7 @@ fn run_test(
|
||||||
} else {
|
} else {
|
||||||
cmd = Command::new(&output_file);
|
cmd = Command::new(&output_file);
|
||||||
if doctest.is_multiple_tests {
|
if doctest.is_multiple_tests {
|
||||||
cmd.arg("*doctest-bin-path");
|
cmd.env("RUSTDOC_DOCTEST_BIN_PATH", &output_file);
|
||||||
cmd.arg(&output_file);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(run_directory) = &rustdoc_options.test_run_directory {
|
if let Some(run_directory) = &rustdoc_options.test_run_directory {
|
||||||
|
|
|
@ -112,8 +112,7 @@ mod __doctest_mod {{
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub static BINARY_PATH: OnceLock<PathBuf> = OnceLock::new();
|
pub static BINARY_PATH: OnceLock<PathBuf> = OnceLock::new();
|
||||||
pub const RUN_OPTION: &str = \"*doctest-inner-test\";
|
pub const RUN_OPTION: &str = \"RUSTDOC_DOCTEST_RUN_NB_TEST\";
|
||||||
pub const BIN_OPTION: &str = \"*doctest-bin-path\";
|
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn doctest_path() -> Option<&'static PathBuf> {{
|
pub fn doctest_path() -> Option<&'static PathBuf> {{
|
||||||
|
@ -123,8 +122,8 @@ mod __doctest_mod {{
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> Result<(), String> {{
|
pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> Result<(), String> {{
|
||||||
let out = std::process::Command::new(bin)
|
let out = std::process::Command::new(bin)
|
||||||
.arg(self::RUN_OPTION)
|
.env(self::RUN_OPTION, test_nb.to_string())
|
||||||
.arg(test_nb.to_string())
|
.args(std::env::args().skip(1).collect::<Vec<_>>())
|
||||||
.output()
|
.output()
|
||||||
.expect(\"failed to run command\");
|
.expect(\"failed to run command\");
|
||||||
if !out.status.success() {{
|
if !out.status.success() {{
|
||||||
|
@ -138,36 +137,27 @@ mod __doctest_mod {{
|
||||||
#[rustc_main]
|
#[rustc_main]
|
||||||
fn main() -> std::process::ExitCode {{
|
fn main() -> std::process::ExitCode {{
|
||||||
const TESTS: [test::TestDescAndFn; {nb_tests}] = [{ids}];
|
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_marker = std::ffi::OsStr::new(__doctest_mod::RUN_OPTION);
|
||||||
let test_args = &[{test_args}];
|
let test_args = &[{test_args}];
|
||||||
|
const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\";
|
||||||
|
|
||||||
let mut args = std::env::args_os().skip(1);
|
if let Ok(binary) = std::env::var(ENV_BIN) {{
|
||||||
while let Some(arg) = args.next() {{
|
let _ = crate::__doctest_mod::BINARY_PATH.set(binary.into());
|
||||||
if arg == bin_marker {{
|
unsafe {{ std::env::remove_var(ENV_BIN); }}
|
||||||
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));
|
return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None));
|
||||||
}} else if arg == test_marker {{
|
}} else if let Ok(nb_test) = std::env::var(__doctest_mod::RUN_OPTION) {{
|
||||||
let Some(nb_test) = args.next() else {{
|
if let Ok(nb_test) = nb_test.parse::<usize>() {{
|
||||||
panic!(\"missing argument after `{{}}`\", __doctest_mod::RUN_OPTION);
|
|
||||||
}};
|
|
||||||
if let Some(nb_test) = nb_test.to_str().and_then(|nb| nb.parse::<usize>().ok()) {{
|
|
||||||
if let Some(test) = TESTS.get(nb_test) {{
|
if let Some(test) = TESTS.get(nb_test) {{
|
||||||
if let test::StaticTestFn(f) = test.testfn {{
|
if let test::StaticTestFn(f) = test.testfn {{
|
||||||
return std::process::Termination::report(f());
|
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))
|
std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None))
|
||||||
}}",
|
}}",
|
||||||
nb_tests = self.nb_tests,
|
nb_tests = self.nb_tests,
|
||||||
|
|
|
@ -242,7 +242,8 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds
|
||||||
bounds
|
bounds
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|bound| {
|
.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
|
&& let [.., path] = poly_trait.trait_ref.path.segments
|
||||||
&& poly_trait.bound_generic_params.is_empty()
|
&& poly_trait.bound_generic_params.is_empty()
|
||||||
&& let Some(trait_def_id) = path.res.opt_def_id()
|
&& 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
|
// 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.
|
// simply comparing trait `DefId`s won't be enough. We also need to compare the generics.
|
||||||
for (index, bound) in bounds.iter().enumerate() {
|
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 [.., path] = poly_trait.trait_ref.path.segments
|
||||||
&& let implied_args = path.args.map_or([].as_slice(), |a| a.args)
|
&& let implied_args = path.args.map_or([].as_slice(), |a| a.args)
|
||||||
&& let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints)
|
&& let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints)
|
||||||
|
|
|
@ -310,7 +310,7 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&
|
||||||
if let ty::Alias(_, alias_ty) = ty.kind()
|
if let ty::Alias(_, alias_ty) = ty.kind()
|
||||||
&& let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
|
&& let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
|
||||||
&& let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin
|
&& 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(segment) = trait_ref.trait_ref.path.segments.last()
|
||||||
&& let Some(generic_args) = segment.args
|
&& let Some(generic_args) = segment.args
|
||||||
&& let [constraint] = generic_args.constraints
|
&& let [constraint] = generic_args.constraints
|
||||||
|
|
|
@ -163,7 +163,7 @@ fn check_fn_inner<'tcx>(
|
||||||
if visitor.lts.iter().any(|lt| matches!(lt.res, LifetimeName::Param(_))) {
|
if visitor.lts.iter().any(|lt| matches!(lt.res, LifetimeName::Param(_))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let GenericBound::Trait(ref trait_ref, _) = *bound {
|
if let GenericBound::Trait(ref trait_ref) = *bound {
|
||||||
let params = &trait_ref
|
let params = &trait_ref
|
||||||
.trait_ref
|
.trait_ref
|
||||||
.path
|
.path
|
||||||
|
@ -438,7 +438,7 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
|
||||||
if !lt.is_elided() {
|
if !lt.is_elided() {
|
||||||
self.unelided_trait_object_lifetime = true;
|
self.unelided_trait_object_lifetime = true;
|
||||||
}
|
}
|
||||||
for (bound, _) in bounds {
|
for bound in bounds {
|
||||||
self.visit_poly_trait_ref(bound);
|
self.visit_poly_trait_ref(bound);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -107,7 +107,7 @@ fn future_trait_ref<'tcx>(
|
||||||
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
|
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
|
||||||
if let TyKind::OpaqueDef(opaque, bounds) = ty.kind
|
if let TyKind::OpaqueDef(opaque, bounds) = ty.kind
|
||||||
&& let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
|
&& 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)
|
Some(&poly.trait_ref)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -40,7 +40,6 @@ struct Bound<'tcx> {
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
|
|
||||||
trait_bound: &'tcx PolyTraitRef<'tcx>,
|
trait_bound: &'tcx PolyTraitRef<'tcx>,
|
||||||
modifier: TraitBoundModifier,
|
|
||||||
|
|
||||||
predicate_pos: usize,
|
predicate_pos: usize,
|
||||||
bound_pos: usize,
|
bound_pos: usize,
|
||||||
|
@ -65,11 +64,10 @@ fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator<Item
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(move |(bound_pos, bound)| match bound {
|
.filter_map(move |(bound_pos, bound)| match bound {
|
||||||
&GenericBound::Trait(ref trait_bound, modifier) => Some(Bound {
|
&GenericBound::Trait(ref trait_bound) => Some(Bound {
|
||||||
param,
|
param,
|
||||||
ident,
|
ident,
|
||||||
trait_bound,
|
trait_bound,
|
||||||
modifier,
|
|
||||||
predicate_pos,
|
predicate_pos,
|
||||||
bound_pos,
|
bound_pos,
|
||||||
}),
|
}),
|
||||||
|
@ -120,13 +118,13 @@ impl LateLintPass<'_> for NeedlessMaybeSized {
|
||||||
let maybe_sized_params: DefIdMap<_> = type_param_bounds(generics)
|
let maybe_sized_params: DefIdMap<_> = type_param_bounds(generics)
|
||||||
.filter(|bound| {
|
.filter(|bound| {
|
||||||
bound.trait_bound.trait_ref.trait_def_id() == Some(sized_trait)
|
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))
|
.map(|bound| (bound.param, bound))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for bound in type_param_bounds(generics) {
|
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(sized_bound) = maybe_sized_params.get(&bound.param)
|
||||||
&& let Some(path) = path_to_sized_bound(cx, bound.trait_bound)
|
&& let Some(path) = path_to_sized_bound(cx, bound.trait_bound)
|
||||||
{
|
{
|
||||||
|
|
|
@ -182,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
|
||||||
|
|
||||||
// Iterate the bounds and add them to our seen hash
|
// Iterate the bounds and add them to our seen hash
|
||||||
// If we haven't yet seen it, add it to the fixed traits
|
// 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 {
|
let Some(def_id) = bound.trait_ref.trait_def_id() else {
|
||||||
continue;
|
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,
|
// 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
|
// there must be 1 or more duplicates
|
||||||
if bounds.len() != unique_traits.len() {
|
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);
|
bounds_span = bounds_span.to(bound.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +229,8 @@ impl TraitBounds {
|
||||||
/// this MSRV? See <https://github.com/rust-lang/rust-clippy/issues/8772> for details.
|
/// this MSRV? See <https://github.com/rust-lang/rust-clippy/issues/8772> for details.
|
||||||
fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool {
|
fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool {
|
||||||
if !self.msrv.meets(msrvs::MAYBE_BOUND_IN_WHERE)
|
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()
|
cx.tcx.lang_items().get(LangItem::Sized) == tr.trait_ref.path.res.opt_def_id()
|
||||||
} else {
|
} 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)> {
|
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_path = t.trait_ref.path;
|
||||||
let trait_span = {
|
let trait_span = {
|
||||||
let path_span = trait_path.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 `?`
|
path_span.with_lo(path_span.lo() - BytePos(1)) // include the `?`
|
||||||
} else {
|
} else {
|
||||||
path_span
|
path_span
|
||||||
|
@ -430,7 +431,7 @@ fn rollup_traits(
|
||||||
let mut repeated_res = false;
|
let mut repeated_res = false;
|
||||||
|
|
||||||
let only_comparable_trait_refs = |bound: &GenericBound<'_>| {
|
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))
|
Some((into_comparable_trait_ref(&t.trait_ref), t.span))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -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.
|
// Returns true if given type is `Any` trait.
|
||||||
fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool {
|
fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool {
|
||||||
if let TyKind::TraitObject(traits, ..) = t.kind {
|
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()
|
if let Some(trait_did) = bound.trait_ref.trait_def_id()
|
||||||
&& cx.tcx.is_diagnostic_item(sym::Any, trait_did)
|
&& cx.tcx.is_diagnostic_item(sym::Any, trait_did)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,7 +55,6 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
|
||||||
TyKind::TraitObject(param_bounds, _, _) => {
|
TyKind::TraitObject(param_bounds, _, _) => {
|
||||||
let has_lifetime_parameters = param_bounds.iter().any(|bound| {
|
let has_lifetime_parameters = param_bounds.iter().any(|bound| {
|
||||||
bound
|
bound
|
||||||
.0
|
|
||||||
.bound_generic_params
|
.bound_generic_params
|
||||||
.iter()
|
.iter()
|
||||||
.any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
|
.any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
|
||||||
|
|
|
@ -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 {
|
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| {
|
&& over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
|
||||||
eq_generic_param(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 {
|
pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool {
|
||||||
use GenericBound::*;
|
use GenericBound::*;
|
||||||
match (l, r) {
|
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),
|
(Outlives(l), Outlives(r)) => eq_id(l.ident, r.ident),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -759,14 +759,8 @@ pub fn output_testname_unique(
|
||||||
/// test/revision should reside. Example:
|
/// test/revision should reside. Example:
|
||||||
/// /path/to/build/host-triple/test/ui/relative/testname.revision.mode/
|
/// /path/to/build/host-triple/test/ui/relative/testname.revision.mode/
|
||||||
pub fn output_base_dir(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf {
|
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)
|
output_relative_path(config, &testpaths.relative_dir)
|
||||||
.join(output_testname_unique(config, testpaths, revision))
|
.join(output_testname_unique(config, testpaths, revision))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Absolute path to the base filename used as output for the given
|
/// Absolute path to the base filename used as output for the given
|
||||||
|
|
|
@ -235,7 +235,9 @@ try:
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
cur_commit = sys.argv[1]
|
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]
|
cur_commit_msg = sys.argv[2]
|
||||||
save_message_to_path = sys.argv[3]
|
save_message_to_path = sys.argv[3]
|
||||||
github_token = sys.argv[4]
|
github_token = sys.argv[4]
|
||||||
|
|
|
@ -180,7 +180,7 @@ impl Spanned for ast::GenericArg {
|
||||||
impl Spanned for ast::GenericBound {
|
impl Spanned for ast::GenericBound {
|
||||||
fn span(&self) -> Span {
|
fn span(&self) -> Span {
|
||||||
match *self {
|
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::Outlives(ref l) => l.ident.span,
|
||||||
ast::GenericBound::Use(_, span) => span,
|
ast::GenericBound::Use(_, span) => span,
|
||||||
}
|
}
|
||||||
|
|
|
@ -610,16 +610,14 @@ impl Rewrite for ast::GenericBound {
|
||||||
|
|
||||||
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
|
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
|
||||||
match *self {
|
match *self {
|
||||||
ast::GenericBound::Trait(
|
ast::GenericBound::Trait(ref poly_trait_ref) => {
|
||||||
ref poly_trait_ref,
|
let snippet = context.snippet(self.span());
|
||||||
ast::TraitBoundModifiers {
|
let has_paren = snippet.starts_with('(') && snippet.ends_with(')');
|
||||||
|
let ast::TraitBoundModifiers {
|
||||||
constness,
|
constness,
|
||||||
asyncness,
|
asyncness,
|
||||||
polarity,
|
polarity,
|
||||||
},
|
} = poly_trait_ref.modifiers;
|
||||||
) => {
|
|
||||||
let snippet = context.snippet(self.span());
|
|
||||||
let has_paren = snippet.starts_with('(') && snippet.ends_with(')');
|
|
||||||
let mut constness = constness.as_str().to_string();
|
let mut constness = constness.as_str().to_string();
|
||||||
if !constness.is_empty() {
|
if !constness.is_empty() {
|
||||||
constness.push(' ');
|
constness.push(' ');
|
||||||
|
|
|
@ -29,7 +29,7 @@ The setup for the `rmake.rs` version is a 3-stage process:
|
||||||
structure within `build/<target>/test/run-make/`
|
structure within `build/<target>/test/run-make/`
|
||||||
|
|
||||||
```
|
```
|
||||||
<test-name>/
|
<test-name>/<test-name>/
|
||||||
rmake.exe # recipe binary
|
rmake.exe # recipe binary
|
||||||
rmake_out/ # sources from test sources copied over
|
rmake_out/ # sources from test sources copied over
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = env!("NON_UNICODE_VAR");
|
let _ = env!("NON_UNICODE_VAR");
|
||||||
|
let _ = option_env!("NON_UNICODE_VAR");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,7 @@ struct ErrorWithNonexistentField {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
//~^ ERROR invalid format string: expected `'}'`
|
//~^ ERROR invalid format string: expected `}`
|
||||||
#[diag(no_crate_example, code = E0123)]
|
#[diag(no_crate_example, code = E0123)]
|
||||||
struct ErrorMissingClosingBrace {
|
struct ErrorMissingClosingBrace {
|
||||||
#[suggestion(no_crate_suggestion, code = "{name")]
|
#[suggestion(no_crate_suggestion, code = "{name")]
|
||||||
|
|
|
@ -184,11 +184,11 @@ error: `name` doesn't refer to a field on this type
|
||||||
LL | #[suggestion(no_crate_suggestion, code = "{name}")]
|
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
|
--> $DIR/diagnostic-derive.rs:180:10
|
||||||
|
|
|
|
||||||
LL | #[derive(Diagnostic)]
|
LL | #[derive(Diagnostic)]
|
||||||
| ^^^^^^^^^^ expected `'}'` in format string
|
| ^^^^^^^^^^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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)
|
= note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
|
@ -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
|
--> $DIR/unsupported.rs:35:15
|
||||||
|
|
|
|
||||||
LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:49:17
|
||||||
|
|
|
|
||||||
LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:71:18
|
||||||
|
|
|
|
||||||
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:81:15
|
||||||
|
|
|
|
||||||
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:94:17
|
||||||
|
|
|
|
||||||
LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:116:15
|
||||||
|
|
|
|
||||||
LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:139:20
|
||||||
|
|
|
|
||||||
LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:170:19
|
||||||
|
|
|
|
||||||
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
||||||
|
@ -123,7 +123,7 @@ LL | extern "stdcall" {}
|
||||||
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
|
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
|
||||||
= note: `#[warn(unsupported_calling_conventions)]` on by default
|
= 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
|
--> $DIR/unsupported.rs:195:21
|
||||||
|
|
|
|
||||||
LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
|
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!
|
= 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 <https://github.com/rust-lang/rust/issues/130260>
|
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/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
|
--> $DIR/unsupported.rs:203:22
|
||||||
|
|
|
|
||||||
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
||||||
|
|
|
@ -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
|
--> $DIR/unsupported.rs:35:15
|
||||||
|
|
|
|
||||||
LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:71:18
|
||||||
|
|
|
|
||||||
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:81:15
|
||||||
|
|
|
|
||||||
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:94:17
|
||||||
|
|
|
|
||||||
LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:116:15
|
||||||
|
|
|
|
||||||
LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:139:20
|
||||||
|
|
|
|
||||||
LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:170:19
|
||||||
|
|
|
|
||||||
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
||||||
|
@ -108,7 +108,7 @@ LL | extern "stdcall" {}
|
||||||
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
|
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
|
||||||
= note: `#[warn(unsupported_calling_conventions)]` on by default
|
= 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
|
--> $DIR/unsupported.rs:195:21
|
||||||
|
|
|
|
||||||
LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
|
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!
|
= 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 <https://github.com/rust-lang/rust/issues/130260>
|
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/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
|
--> $DIR/unsupported.rs:203:22
|
||||||
|
|
|
|
||||||
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
||||||
|
|
|
@ -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
|
--> $DIR/unsupported.rs:35:15
|
||||||
|
|
|
|
||||||
LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:49:17
|
||||||
|
|
|
|
||||||
LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:71:18
|
||||||
|
|
|
|
||||||
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:81:15
|
||||||
|
|
|
|
||||||
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:94:17
|
||||||
|
|
|
|
||||||
LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:195:21
|
||||||
|
|
|
|
||||||
LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
|
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!
|
= 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 <https://github.com/rust-lang/rust/issues/130260>
|
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/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
|
--> $DIR/unsupported.rs:203:22
|
||||||
|
|
|
|
||||||
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
||||||
|
|
|
@ -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
|
--> $DIR/unsupported.rs:35:15
|
||||||
|
|
|
|
||||||
LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:49:17
|
||||||
|
|
|
|
||||||
LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:71:18
|
||||||
|
|
|
|
||||||
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:81:15
|
||||||
|
|
|
|
||||||
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:116:15
|
||||||
|
|
|
|
||||||
LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:139:20
|
||||||
|
|
|
|
||||||
LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:170:19
|
||||||
|
|
|
|
||||||
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
||||||
|
@ -108,7 +108,7 @@ LL | extern "stdcall" {}
|
||||||
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
|
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
|
||||||
= note: `#[warn(unsupported_calling_conventions)]` on by default
|
= 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
|
--> $DIR/unsupported.rs:195:21
|
||||||
|
|
|
|
||||||
LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
|
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!
|
= 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 <https://github.com/rust-lang/rust/issues/130260>
|
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/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
|
--> $DIR/unsupported.rs:203:22
|
||||||
|
|
|
|
||||||
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
||||||
|
|
|
@ -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
|
--> $DIR/unsupported.rs:35:15
|
||||||
|
|
|
|
||||||
LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:49:17
|
||||||
|
|
|
|
||||||
LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:71:18
|
||||||
|
|
|
|
||||||
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:81:15
|
||||||
|
|
|
|
||||||
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:116:15
|
||||||
|
|
|
|
||||||
LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:139:20
|
||||||
|
|
|
|
||||||
LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:170:19
|
||||||
|
|
|
|
||||||
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
||||||
|
@ -108,7 +108,7 @@ LL | extern "stdcall" {}
|
||||||
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
|
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
|
||||||
= note: `#[warn(unsupported_calling_conventions)]` on by default
|
= 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
|
--> $DIR/unsupported.rs:195:21
|
||||||
|
|
|
|
||||||
LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
|
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!
|
= 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 <https://github.com/rust-lang/rust/issues/130260>
|
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/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
|
--> $DIR/unsupported.rs:203:22
|
||||||
|
|
|
|
||||||
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
||||||
|
|
|
@ -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
|
--> $DIR/unsupported.rs:35:15
|
||||||
|
|
|
|
||||||
LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:49:17
|
||||||
|
|
|
|
||||||
LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:71:18
|
||||||
|
|
|
|
||||||
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:81:15
|
||||||
|
|
|
|
||||||
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:94:17
|
||||||
|
|
|
|
||||||
LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:139:20
|
||||||
|
|
|
|
||||||
LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
|
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" {}
|
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
|
--> $DIR/unsupported.rs:170:19
|
||||||
|
|
|
|
||||||
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
|
||||||
|
@ -108,7 +108,7 @@ LL | extern "stdcall" {}
|
||||||
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
|
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
|
||||||
= note: `#[warn(unsupported_calling_conventions)]` on by default
|
= 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
|
--> $DIR/unsupported.rs:195:21
|
||||||
|
|
|
|
||||||
LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
|
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!
|
= 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 <https://github.com/rust-lang/rust/issues/130260>
|
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/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
|
--> $DIR/unsupported.rs:203:22
|
||||||
|
|
|
|
||||||
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
|
||||||
|
|
|
@ -19,8 +19,8 @@ trait ImportantTrait3 {}
|
||||||
trait ImportantTrait4 {}
|
trait ImportantTrait4 {}
|
||||||
|
|
||||||
#[diagnostic::on_unimplemented(message = "Test {Self:!}")]
|
#[diagnostic::on_unimplemented(message = "Test {Self:!}")]
|
||||||
//~^WARN expected `'}'`, found `'!'`
|
//~^WARN expected `}`, found `!`
|
||||||
//~|WARN expected `'}'`, found `'!'`
|
//~|WARN expected `}`, found `!`
|
||||||
//~|WARN unmatched `}` found
|
//~|WARN unmatched `}` found
|
||||||
//~|WARN unmatched `}` found
|
//~|WARN unmatched `}` found
|
||||||
trait ImportantTrait5 {}
|
trait ImportantTrait5 {}
|
||||||
|
|
|
@ -30,7 +30,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")]
|
||||||
|
|
|
|
||||||
= help: no format specifier are supported in this position
|
= help: no format specifier are supported in this position
|
||||||
|
|
||||||
warning: expected `'}'`, found `'!'`
|
warning: expected `}`, found `!`
|
||||||
--> $DIR/broken_format.rs:21:32
|
--> $DIR/broken_format.rs:21:32
|
||||||
|
|
|
|
||||||
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
|
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) {}
|
LL | fn check_4(_: impl ImportantTrait4) {}
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `check_4`
|
| ^^^^^^^^^^^^^^^ required by this bound in `check_4`
|
||||||
|
|
||||||
warning: expected `'}'`, found `'!'`
|
warning: expected `}`, found `!`
|
||||||
--> $DIR/broken_format.rs:21:32
|
--> $DIR/broken_format.rs:21:32
|
||||||
|
|
|
|
||||||
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
|
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world! {0:}<3", 2);
|
println!("Hello, world! {0:}<3", 2);
|
||||||
//~^ ERROR invalid format string: expected `'}'` but string was terminated
|
//~^ ERROR invalid format string: expected `}` but string was terminated
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/closing-brace-as-fill.rs:6:35
|
||||||
|
|
|
|
||||||
LL | println!("Hello, world! {0:}<3", 2);
|
LL | println!("Hello, world! {0:}<3", 2);
|
||||||
| - ^ expected `'}'` in format string
|
| - ^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| this is not interpreted as a formatting closing brace
|
| 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
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ raw { \n
|
||||||
|
|
||||||
// note: `\x7B` is `{`
|
// note: `\x7B` is `{`
|
||||||
println!("\x7B}\u{8} {", 1);
|
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);
|
println!("\x7B}\u8 {", 1);
|
||||||
//~^ ERROR incorrect unicode escape sequence
|
//~^ ERROR incorrect unicode escape sequence
|
||||||
|
|
|
@ -9,138 +9,138 @@ help: format of unicode escape sequences uses braces
|
||||||
LL | println!("\x7B}\u{8} {", 1);
|
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
|
--> $DIR/format-string-error-2.rs:5:5
|
||||||
|
|
|
|
||||||
LL | format!("{
|
LL | format!("{
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL | a");
|
LL | a");
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:9:5
|
||||||
|
|
|
|
||||||
LL | format!("{ \
|
LL | format!("{ \
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL | \
|
LL | \
|
||||||
LL | b");
|
LL | b");
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:11:18
|
||||||
|
|
|
|
||||||
LL | format!(r#"{ \
|
LL | format!(r#"{ \
|
||||||
| - ^ expected `'}'` in format string
|
| - ^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:15:18
|
||||||
|
|
|
|
||||||
LL | format!(r#"{ \n
|
LL | format!(r#"{ \n
|
||||||
| - ^ expected `'}'` in format string
|
| - ^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:21:5
|
||||||
|
|
|
|
||||||
LL | format!("{ \n
|
LL | format!("{ \n
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL | \n
|
LL | \n
|
||||||
LL | e");
|
LL | e");
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:25:5
|
||||||
|
|
|
|
||||||
LL | {
|
LL | {
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL | a");
|
LL | a");
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:29:5
|
||||||
|
|
|
|
||||||
LL | {
|
LL | {
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL | a
|
LL | a
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:35:5
|
||||||
|
|
|
|
||||||
LL | { \
|
LL | { \
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL | \
|
LL | \
|
||||||
LL | b");
|
LL | b");
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:40:5
|
||||||
|
|
|
|
||||||
LL | { \
|
LL | { \
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL | \
|
LL | \
|
||||||
LL | b \
|
LL | b \
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:45:8
|
||||||
|
|
|
|
||||||
LL | raw { \
|
LL | raw { \
|
||||||
| - ^ expected `'}'` in format string
|
| - ^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:50:8
|
||||||
|
|
|
|
||||||
LL | raw { \n
|
LL | raw { \n
|
||||||
| - ^ expected `'}'` in format string
|
| - ^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:57:5
|
||||||
|
|
|
|
||||||
LL | { \n
|
LL | { \n
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL | \n
|
LL | \n
|
||||||
LL | e");
|
LL | e");
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error-2.rs:67:5
|
||||||
|
|
|
|
||||||
LL | {
|
LL | {
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL | asdf}
|
LL | asdf}
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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{}");
|
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
|
--> $DIR/format-string-error-2.rs:74:27
|
||||||
|
|
|
|
||||||
LL | println!("\x7B}\u{8} {", 1);
|
LL | println!("\x7B}\u{8} {", 1);
|
||||||
| -^ expected `'}'` in format string
|
| -^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{");
|
println!("{");
|
||||||
//~^ ERROR invalid format string: expected `'}'` but string was terminated
|
//~^ ERROR invalid format string: expected `}` but string was terminated
|
||||||
println!("{{}}");
|
println!("{{}}");
|
||||||
println!("}");
|
println!("}");
|
||||||
//~^ ERROR invalid format string: unmatched `}` found
|
//~^ ERROR invalid format string: unmatched `}` found
|
||||||
|
@ -13,11 +13,11 @@ fn main() {
|
||||||
let _ = format!("{a:._$}", a = "", _ = 0);
|
let _ = format!("{a:._$}", a = "", _ = 0);
|
||||||
//~^ ERROR invalid format string: invalid argument name `_`
|
//~^ ERROR invalid format string: invalid argument name `_`
|
||||||
let _ = format!("{");
|
let _ = format!("{");
|
||||||
//~^ ERROR invalid format string: expected `'}'` but string was terminated
|
//~^ ERROR invalid format string: expected `}` but string was terminated
|
||||||
let _ = format!("}");
|
let _ = format!("}");
|
||||||
//~^ ERROR invalid format string: unmatched `}` found
|
//~^ ERROR invalid format string: unmatched `}` found
|
||||||
let _ = format!("{\\}");
|
let _ = format!("{\\}");
|
||||||
//~^ ERROR invalid format string: expected `'}'`, found `'\'`
|
//~^ ERROR invalid format string: expected `}`, found `\`
|
||||||
let _ = format!("\n\n\n{\n\n\n");
|
let _ = format!("\n\n\n{\n\n\n");
|
||||||
//~^ ERROR invalid format string
|
//~^ ERROR invalid format string
|
||||||
let _ = format!(r###"
|
let _ = format!(r###"
|
||||||
|
|
|
@ -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
|
--> $DIR/format-string-error.rs:4:16
|
||||||
|
|
|
|
||||||
LL | println!("{");
|
LL | println!("{");
|
||||||
| -^ expected `'}'` in format string
|
| -^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
|
@ -40,11 +40,11 @@ LL | let _ = format!("{a:._$}", a = "", _ = 0);
|
||||||
|
|
|
|
||||||
= note: argument name cannot be a single underscore
|
= 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
|
--> $DIR/format-string-error.rs:15:23
|
||||||
|
|
|
|
||||||
LL | let _ = format!("{");
|
LL | let _ = format!("{");
|
||||||
| -^ expected `'}'` in format string
|
| -^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
|
@ -58,44 +58,44 @@ LL | let _ = format!("}");
|
||||||
|
|
|
|
||||||
= note: if you intended to print `}`, you can escape it using `}}`
|
= 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
|
--> $DIR/format-string-error.rs:19:23
|
||||||
|
|
|
|
||||||
LL | let _ = format!("{\}");
|
LL | let _ = format!("{\}");
|
||||||
| -^ expected `'}'` in format string
|
| -^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error.rs:21:35
|
||||||
|
|
|
|
||||||
LL | let _ = format!("\n\n\n{\n\n\n");
|
LL | let _ = format!("\n\n\n{\n\n\n");
|
||||||
| - ^ expected `'}'` in format string
|
| - ^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error.rs:27:3
|
||||||
|
|
|
|
||||||
LL | {"###);
|
LL | {"###);
|
||||||
| -^ expected `'}'` in format string
|
| -^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-error.rs:35:1
|
||||||
|
|
|
|
||||||
LL | {
|
LL | {
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL |
|
LL |
|
||||||
LL | "###);
|
LL | "###);
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= note: if you intended to print `{`, you can escape it using `{{`
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ fn main() {
|
||||||
format!("{?:?}", bar);
|
format!("{?:?}", bar);
|
||||||
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
||||||
format!("{??}", bar);
|
format!("{??}", bar);
|
||||||
//~^ ERROR invalid format string: expected `'}'`, found `'?'`
|
//~^ ERROR invalid format string: expected `}`, found `?`
|
||||||
format!("{?;bar}");
|
format!("{?;bar}");
|
||||||
//~^ ERROR invalid format string: expected `'}'`, found `'?'`
|
//~^ ERROR invalid format string: expected `}`, found `?`
|
||||||
format!("{?:#?}", bar);
|
format!("{?:#?}", bar);
|
||||||
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
||||||
format!("Hello {<5:}!", "x");
|
format!("Hello {<5:}!", "x");
|
||||||
|
|
|
@ -22,21 +22,21 @@ LL | format!("{?:?}", bar);
|
||||||
|
|
|
|
||||||
= note: `?` comes after `:`, try `:?` instead
|
= 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
|
--> $DIR/format-string-wrong-order.rs:9:15
|
||||||
|
|
|
|
||||||
LL | format!("{??}", bar);
|
LL | format!("{??}", bar);
|
||||||
| -^ expected `'}'` in format string
|
| -^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= 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
|
--> $DIR/format-string-wrong-order.rs:11:15
|
||||||
|
|
|
|
||||||
LL | format!("{?;bar}");
|
LL | format!("{?;bar}");
|
||||||
| -^ expected `'}'` in format string
|
| -^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
|
|
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ fn main() {
|
||||||
|
|
||||||
// bad syntax of the format string
|
// 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 } bar"); //~ ERROR: unmatched `}` found
|
||||||
format!("foo }"); //~ ERROR: unmatched `}` found
|
format!("foo }"); //~ ERROR: unmatched `}` found
|
||||||
|
|
|
@ -136,11 +136,11 @@ LL | format!("{valuea} {valueb}", valuea=5, valuec=7);
|
||||||
| |
|
| |
|
||||||
| formatting specifier missing
|
| 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
|
--> $DIR/ifmt-bad-arg.rs:51:15
|
||||||
|
|
|
|
||||||
LL | format!("{");
|
LL | format!("{");
|
||||||
| -^ expected `'}'` in format string
|
| -^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| 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`
|
= 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
|
--> $DIR/ifmt-bad-arg.rs:75:1
|
||||||
|
|
|
|
||||||
LL | ninth number: {
|
LL | ninth number: {
|
||||||
| - because of this opening brace
|
| - because of this opening brace
|
||||||
LL | tenth number: {}",
|
LL | tenth number: {}",
|
||||||
| ^ expected `'}'` in format string
|
| ^ expected `}` in format string
|
||||||
|
|
|
|
||||||
= note: if you intended to print `{`, you can escape it using `{{`
|
= note: if you intended to print `{`, you can escape it using `{{`
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = format!(concat!("{0}𝖳𝖾𝗌𝗍{"), i);
|
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: if you intended to print `{`, you can escape it using `{{`
|
||||||
//~| NOTE: in this expansion of concat!
|
//~| NOTE: in this expansion of concat!
|
||||||
//~| NOTE: in this expansion of concat!
|
//~| NOTE: in this expansion of concat!
|
||||||
//~| NOTE: expected `'}'` in format string
|
//~| NOTE: expected `}` in format string
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/issue-91556.rs:2:19
|
||||||
|
|
|
|
||||||
LL | let _ = format!(concat!("{0}𝖳𝖾𝗌𝗍{"), i);
|
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: 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)
|
= note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
|
@ -4,7 +4,7 @@ extern crate format_string_proc_macro;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
format_string_proc_macro::respan_to_invalid_format_literal!("¡");
|
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!("¡ {"));
|
format_args!(r#concat!("¡ {"));
|
||||||
//~^ ERROR invalid format string: expected `'}'` but string was terminated
|
//~^ ERROR invalid format string: expected `}` but string was terminated
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/respanned-literal-issue-106191.rs:6:65
|
||||||
|
|
|
|
||||||
LL | format_string_proc_macro::respan_to_invalid_format_literal!("¡");
|
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 `{{`
|
= 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
|
--> $DIR/respanned-literal-issue-106191.rs:8:18
|
||||||
|
|
|
|
||||||
LL | format_args!(r#concat!("¡ {"));
|
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: 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)
|
= note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
|
@ -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
|
--> $DIR/issue-51848.rs:6:20
|
||||||
|
|
|
|
||||||
LL | println!("{");
|
LL | println!("{");
|
||||||
| -^ expected `'}'` in format string
|
| -^ expected `}` in format string
|
||||||
| |
|
| |
|
||||||
| because of this opening brace
|
| because of this opening brace
|
||||||
...
|
...
|
||||||
|
|
17
tests/ui/use/unused-trait-with-method-err.rs
Normal file
17
tests/ui/use/unused-trait-with-method-err.rs
Normal file
|
@ -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
|
||||||
|
}
|
19
tests/ui/use/unused-trait-with-method-err.stderr
Normal file
19
tests/ui/use/unused-trait-with-method-err.stderr
Normal file
|
@ -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`.
|
Loading…
Add table
Add a link
Reference in a new issue