diff --git a/RELEASES.md b/RELEASES.md
index 0ecd472efb6e2..2c91ddf782674 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,4 +1,4 @@
-Version 1.80 (2024-07-25)
+Version 1.80.0 (2024-07-25)
==========================
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 75c656973f963..4d19be62df809 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -36,6 +36,7 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
+use std::borrow::Cow;
use std::cmp;
use std::fmt;
use std::mem;
@@ -2272,7 +2273,7 @@ impl std::fmt::Debug for InlineAsmOptions {
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
pub enum InlineAsmTemplatePiece {
- String(String),
+ String(Cow<'static, str>),
Placeholder { operand_idx: usize, modifier: Option, span: Span },
}
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index f990b4ba69b3f..6874505643821 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1525,8 +1525,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
continue;
}
let is_param = *is_param.get_or_insert_with(compute_is_param);
- if !is_param {
- self.dcx().emit_err(MisplacedRelaxTraitBound { span: bound.span() });
+ if !is_param && !self.tcx.features().more_maybe_bounds {
+ self.tcx
+ .sess
+ .create_feature_err(
+ MisplacedRelaxTraitBound { span: bound.span() },
+ sym::more_maybe_bounds,
+ )
+ .emit();
}
}
}
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 0f5f4d8023bd1..218493cb7ead5 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1216,6 +1216,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
itctx,
TraitBoundModifiers::NONE,
);
+ let bound = (bound, hir::TraitBoundModifier::None);
let bounds = this.arena.alloc_from_iter([bound]);
let lifetime_bound = this.elided_dyn_bound(t.span);
(bounds, lifetime_bound)
@@ -1348,21 +1349,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// We can safely ignore constness here since AST validation
// takes care of rejecting invalid modifier combinations and
// const trait bounds in trait object types.
- GenericBound::Trait(ty, modifiers) => match modifiers.polarity {
- BoundPolarity::Positive | BoundPolarity::Negative(_) => {
- Some(this.lower_poly_trait_ref(
- ty,
- itctx,
- // Still, don't pass along the constness here; we don't want to
- // synthesize any host effect args, it'd only cause problems.
- TraitBoundModifiers {
- constness: BoundConstness::Never,
- ..*modifiers
- },
- ))
- }
- BoundPolarity::Maybe(_) => None,
- },
+ GenericBound::Trait(ty, modifiers) => {
+ // Still, don't pass along the constness here; we don't want to
+ // synthesize any host effect args, it'd only cause problems.
+ let modifiers = TraitBoundModifiers {
+ constness: BoundConstness::Never,
+ ..*modifiers
+ };
+ let trait_ref = this.lower_poly_trait_ref(ty, itctx, modifiers);
+ let polarity = this.lower_trait_bound_modifiers(modifiers);
+ Some((trait_ref, polarity))
+ }
GenericBound::Outlives(lifetime) => {
if lifetime_bound.is_none() {
lifetime_bound = Some(this.lower_lifetime(lifetime));
@@ -2688,6 +2685,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
span: self.lower_span(span),
};
+ let principal = (principal, hir::TraitBoundModifier::None);
// The original ID is taken by the `PolyTraitRef`,
// so the `Ty` itself needs a different one.
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 1088db74cc966..9b063a330b746 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1345,14 +1345,28 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
match bound {
GenericBound::Trait(trait_ref, modifiers) => {
match (ctxt, modifiers.constness, modifiers.polarity) {
- (BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
- self.dcx().emit_err(errors::OptionalTraitSupertrait {
- span: trait_ref.span,
- path_str: pprust::path_to_string(&trait_ref.trait_ref.path),
- });
+ (BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_))
+ if !self.features.more_maybe_bounds =>
+ {
+ self.session
+ .create_feature_err(
+ errors::OptionalTraitSupertrait {
+ span: trait_ref.span,
+ path_str: pprust::path_to_string(&trait_ref.trait_ref.path),
+ },
+ sym::more_maybe_bounds,
+ )
+ .emit();
}
- (BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
- self.dcx().emit_err(errors::OptionalTraitObject { span: trait_ref.span });
+ (BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_))
+ if !self.features.more_maybe_bounds =>
+ {
+ self.session
+ .create_feature_err(
+ errors::OptionalTraitObject { span: trait_ref.span },
+ sym::more_maybe_bounds,
+ )
+ .emit();
}
(
BoundKind::TraitObject,
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index dd0f9aaf22104..b8fe6338493d0 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -459,7 +459,7 @@ fn expand_preparsed_asm(
for (i, template_expr) in args.templates.into_iter().enumerate() {
if i != 0 {
- template.push(ast::InlineAsmTemplatePiece::String("\n".to_string()));
+ template.push(ast::InlineAsmTemplatePiece::String("\n".into()));
}
let msg = "asm template must be a string literal";
@@ -527,7 +527,7 @@ fn expand_preparsed_asm(
// Don't treat raw asm as a format string.
if args.options.contains(ast::InlineAsmOptions::RAW) {
- template.push(ast::InlineAsmTemplatePiece::String(template_str.to_string()));
+ template.push(ast::InlineAsmTemplatePiece::String(template_str.to_string().into()));
let template_num_lines = 1 + template_str.matches('\n').count();
line_spans.extend(std::iter::repeat(template_sp).take(template_num_lines));
continue;
@@ -577,7 +577,7 @@ fn expand_preparsed_asm(
for piece in unverified_pieces {
match piece {
parse::Piece::String(s) => {
- template.push(ast::InlineAsmTemplatePiece::String(s.to_string()))
+ template.push(ast::InlineAsmTemplatePiece::String(s.to_string().into()))
}
parse::Piece::NextArgument(arg) => {
let span = arg_spans.next().unwrap_or(template_sp);
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index c88230c936056..16edec47e1029 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -46,9 +46,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>(
// Used by panic_abort on Windows, but uses a syntax which only happens to work with
// asm!() by accident and breaks with the GNU assembler as well as global_asm!() for
// the LLVM backend.
- if template.len() == 1
- && template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string())
- {
+ if template.len() == 1 && template[0] == InlineAsmTemplatePiece::String("int $$0x29".into()) {
fx.bcx.ins().trap(TrapCode::User(1));
return;
}
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
index e1896138e487b..a20faa2cad3a8 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -40,7 +40,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
shl rdx, 32
or rax, rdx
"
- .to_string(),
+ .into(),
)],
&[
CInlineAsmOperand::In {
@@ -471,7 +471,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
// into 0x80000000 for which Cranelift doesn't have a native instruction.
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String(format!("cvtps2dq xmm0, xmm0"))],
+ &[InlineAsmTemplatePiece::String("cvtps2dq xmm0, xmm0".into())],
&[CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
_late: true,
@@ -875,7 +875,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String(asm.to_string())],
+ &[InlineAsmTemplatePiece::String(asm.into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
@@ -914,7 +914,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String(format!("pcmpestri xmm0, xmm1, {imm8}"))],
+ &[InlineAsmTemplatePiece::String(format!("pcmpestri xmm0, xmm1, {imm8}").into())],
&[
CInlineAsmOperand::In {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
@@ -967,7 +967,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String(format!("pcmpestrm xmm0, xmm1, {imm8}"))],
+ &[InlineAsmTemplatePiece::String(format!("pcmpestrm xmm0, xmm1, {imm8}").into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
@@ -1015,7 +1015,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String(format!("pclmulqdq xmm0, xmm1, {imm8}"))],
+ &[InlineAsmTemplatePiece::String(format!("pclmulqdq xmm0, xmm1, {imm8}").into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
@@ -1052,7 +1052,9 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String(format!("aeskeygenassist xmm0, xmm0, {imm8}"))],
+ &[InlineAsmTemplatePiece::String(
+ format!("aeskeygenassist xmm0, xmm0, {imm8}").into(),
+ )],
&[CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
_late: true,
@@ -1071,7 +1073,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("aesimc xmm0, xmm0".to_string())],
+ &[InlineAsmTemplatePiece::String("aesimc xmm0, xmm0".into())],
&[CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
_late: true,
@@ -1091,7 +1093,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("aesenc xmm0, xmm1".to_string())],
+ &[InlineAsmTemplatePiece::String("aesenc xmm0, xmm1".into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
@@ -1117,7 +1119,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("aesenclast xmm0, xmm1".to_string())],
+ &[InlineAsmTemplatePiece::String("aesenclast xmm0, xmm1".into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
@@ -1143,7 +1145,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("aesdec xmm0, xmm1".to_string())],
+ &[InlineAsmTemplatePiece::String("aesdec xmm0, xmm1".into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
@@ -1169,7 +1171,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("aesdeclast xmm0, xmm1".to_string())],
+ &[InlineAsmTemplatePiece::String("aesdeclast xmm0, xmm1".into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
@@ -1207,7 +1209,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String(format!("sha1rnds4 xmm1, xmm2, {func}"))],
+ &[InlineAsmTemplatePiece::String(format!("sha1rnds4 xmm1, xmm2, {func}").into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
@@ -1233,7 +1235,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("sha1msg1 xmm1, xmm2".to_string())],
+ &[InlineAsmTemplatePiece::String("sha1msg1 xmm1, xmm2".into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
@@ -1259,7 +1261,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("sha1msg2 xmm1, xmm2".to_string())],
+ &[InlineAsmTemplatePiece::String("sha1msg2 xmm1, xmm2".into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
@@ -1285,7 +1287,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("sha1nexte xmm1, xmm2".to_string())],
+ &[InlineAsmTemplatePiece::String("sha1nexte xmm1, xmm2".into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
@@ -1312,7 +1314,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("sha256rnds2 xmm1, xmm2".to_string())],
+ &[InlineAsmTemplatePiece::String("sha256rnds2 xmm1, xmm2".into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
@@ -1343,7 +1345,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("sha256msg1 xmm1, xmm2".to_string())],
+ &[InlineAsmTemplatePiece::String("sha256msg1 xmm1, xmm2".into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
@@ -1369,7 +1371,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("sha256msg2 xmm1, xmm2".to_string())],
+ &[InlineAsmTemplatePiece::String("sha256msg2 xmm1, xmm2".into())],
&[
CInlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
@@ -1435,7 +1437,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
let edx_place = res_place.place_field(fx, FieldIdx::new(1));
codegen_inline_asm_inner(
fx,
- &[InlineAsmTemplatePiece::String("rdtsc".to_string())],
+ &[InlineAsmTemplatePiece::String("rdtsc".into())],
&[
CInlineAsmOperand::Out {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 9b5ed3b0876a5..d3d071810962b 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -205,6 +205,8 @@ declare_features! (
(unstable, lifetime_capture_rules_2024, "1.76.0", None),
/// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406
(unstable, link_cfg, "1.14.0", None),
+ /// Allows using `?Trait` trait bounds in more contexts.
+ (internal, more_maybe_bounds, "CURRENT_RUSTC_VERSION", None),
/// Allows the `multiple_supertrait_upcastable` lint.
(unstable, multiple_supertrait_upcastable, "1.69.0", None),
/// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 20b15499234ec..8c8f760bc41dc 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2832,7 +2832,11 @@ pub enum TyKind<'hir> {
OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool),
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
- TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
+ TraitObject(
+ &'hir [(PolyTraitRef<'hir>, TraitBoundModifier)],
+ &'hir Lifetime,
+ TraitObjectSyntax,
+ ),
/// Unused for now.
Typeof(&'hir AnonConst),
/// `TyKind::Infer` means the type should be inferred instead of it having been
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index c202ee41e3132..696f548f1ba07 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -902,7 +902,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
try_visit!(visitor.visit_array_length(length));
}
TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
- walk_list!(visitor, visit_poly_trait_ref, bounds);
+ for (bound, _modifier) in bounds {
+ try_visit!(visitor.visit_poly_trait_ref(bound));
+ }
try_visit!(visitor.visit_lifetime(lifetime));
}
TyKind::Typeof(ref expression) => try_visit!(visitor.visit_anon_const(expression)),
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 0316ef69bf83e..456dc4e4e0704 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -831,7 +831,7 @@ impl<'tcx> TypeVisitor> for GATArgsCollector<'tcx> {
fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
match ty.kind {
- hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments {
+ hir::TyKind::TraitObject([(trait_ref, _)], ..) => match trait_ref.trait_ref.path.segments {
[s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()),
_ => false,
},
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 349dc9ad00ed3..02ea95852f01b 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -652,7 +652,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
debug!(?bounds, ?lifetime, "TraitObject");
let scope = Scope::TraitRefBoundary { s: self.scope };
self.with(scope, |this| {
- for bound in bounds {
+ for (bound, _) in bounds {
this.visit_poly_trait_ref_inner(
bound,
NonLifetimeBinderAllowed::Deny("trait object types"),
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index 6f9c481650b21..f05884f8912b0 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -9,7 +9,7 @@ use rustc_middle::bug;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
use rustc_span::symbol::Ident;
-use rustc_span::{ErrorGuaranteed, Span, Symbol};
+use rustc_span::{sym, ErrorGuaranteed, Span, Symbol};
use rustc_trait_selection::traits;
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
use smallvec::SmallVec;
@@ -75,10 +75,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
}
- if unbounds.len() > 1 {
- self.dcx().emit_err(errors::MultipleRelaxedDefaultBounds {
- spans: unbounds.iter().map(|ptr| ptr.span).collect(),
- });
+ if unbounds.len() > 1 && !tcx.features().more_maybe_bounds {
+ self.tcx()
+ .sess
+ .create_feature_err(
+ errors::MultipleRelaxedDefaultBounds {
+ spans: unbounds.iter().map(|ptr| ptr.span).collect(),
+ },
+ sym::more_maybe_bounds,
+ )
+ .emit();
}
let mut seen_sized_unbound = false;
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 8ff6ced8b3983..e9ec24660898b 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -698,7 +698,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
&self,
associated_types: FxIndexMap>,
potential_assoc_types: Vec,
- trait_bounds: &[hir::PolyTraitRef<'_>],
+ trait_bounds: &[(hir::PolyTraitRef<'_>, hir::TraitBoundModifier)],
) {
if associated_types.values().all(|v| v.is_empty()) {
return;
@@ -744,12 +744,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// related to issue #91997, turbofishes added only when in an expr or pat
let mut in_expr_or_pat = false;
if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
- let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id));
+ let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.0.trait_ref.hir_ref_id));
in_expr_or_pat = match grandparent {
Node::Expr(_) | Node::Pat(_) => true,
_ => false,
};
- match bound.trait_ref.path.segments {
+ match bound.0.trait_ref.path.segments {
// FIXME: `trait_ref.path.span` can point to a full path with multiple
// segments, even though `trait_ref.path.segments` is of length `1`. Work
// around that bug here, even though it should be fixed elsewhere.
@@ -790,7 +790,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// and we can then use their span to indicate this to the user.
let bound_names = trait_bounds
.iter()
- .filter_map(|poly_trait_ref| {
+ .filter_map(|(poly_trait_ref, _)| {
let path = poly_trait_ref.trait_ref.path.segments.last()?;
let args = path.args?;
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index 29c71c3fa50b5..e7aad0a29c50c 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -34,7 +34,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.ok()
.is_some_and(|s| s.trim_end().ends_with('<'));
- let is_global = poly_trait_ref.trait_ref.path.is_global();
+ let is_global = poly_trait_ref.0.trait_ref.path.is_global();
let mut sugg = vec![(
self_ty.span.shrink_to_lo(),
@@ -176,7 +176,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let mut is_downgradable = true;
let is_object_safe = match self_ty.kind {
hir::TyKind::TraitObject(objects, ..) => {
- objects.iter().all(|o| match o.trait_ref.path.res {
+ objects.iter().all(|(o, _)| match o.trait_ref.path.res {
Res::Def(DefKind::Trait, id) => {
if Some(id) == owner {
// For recursive traits, don't downgrade the error. (#119652)
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
index aafadc7f9cbea..b3c7a1ff8a8b5 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
@@ -27,7 +27,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
&self,
span: Span,
hir_id: hir::HirId,
- hir_trait_bounds: &[hir::PolyTraitRef<'tcx>],
+ hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)],
lifetime: &hir::Lifetime,
borrowed: bool,
representation: DynKind,
@@ -37,7 +37,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let mut bounds = Bounds::default();
let mut potential_assoc_types = Vec::new();
let dummy_self = self.tcx().types.trait_object_dummy_self;
- for trait_bound in hir_trait_bounds.iter().rev() {
+ for (trait_bound, modifier) in hir_trait_bounds.iter().rev() {
+ if *modifier == hir::TraitBoundModifier::Maybe {
+ continue;
+ }
if let GenericArgCountResult {
correct:
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
@@ -249,7 +252,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let args = tcx.mk_args(&args);
let span = i.bottom().1;
- let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
+ let empty_generic_args = hir_trait_bounds.iter().any(|(hir_bound, _)| {
hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
&& hir_bound.span.contains(span)
});
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index db5eba0d9ebaf..0df9e063904b3 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -300,13 +300,16 @@ impl<'a> State<'a> {
self.word_space("dyn");
}
let mut first = true;
- for bound in bounds {
+ for (bound, modifier) in bounds {
if first {
first = false;
} else {
self.nbsp();
self.word_space("+");
}
+ if *modifier == TraitBoundModifier::Maybe {
+ self.word("?");
+ }
self.print_poly_trait_ref(bound);
}
if !lifetime.is_elided() {
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 2f8eea6cd1816..93c606a954ea4 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -429,7 +429,7 @@ fn ty_has_local_parent(
path_has_local_parent(ty_path, cx, impl_parent, impl_parent_parent)
}
TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => path_has_local_parent(
- principle_poly_trait_ref.trait_ref.path,
+ principle_poly_trait_ref.0.trait_ref.path,
cx,
impl_parent,
impl_parent_parent,
@@ -527,7 +527,7 @@ fn self_ty_kind_for_diagnostic(ty: &rustc_hir::Ty<'_>, tcx: TyCtxt<'_>) -> (Span
.to_string(),
),
TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
- let path = &principle_poly_trait_ref.trait_ref.path;
+ let path = &principle_poly_trait_ref.0.trait_ref.path;
(
path_span_without_args(path),
path.res
diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs
index 6983e7abbd64e..552245f0cdd93 100644
--- a/compiler/rustc_lint/src/traits.rs
+++ b/compiler/rustc_lint/src/traits.rs
@@ -113,9 +113,11 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
let hir::TyKind::TraitObject(bounds, _lifetime, _syntax) = &ty.kind else { return };
- for bound in &bounds[..] {
+ for (bound, modifier) in &bounds[..] {
let def_id = bound.trait_ref.trait_def_id();
- if cx.tcx.lang_items().drop_trait() == def_id {
+ if cx.tcx.lang_items().drop_trait() == def_id
+ && *modifier != hir::TraitBoundModifier::Maybe
+ {
let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return };
cx.emit_span_lint(DYN_DROP, bound.span, DropGlue { tcx: cx.tcx, def_id });
}
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 99afb500e0b6f..5f13b329de40d 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -3,7 +3,6 @@ use crate::thir::cx::region::Scope;
use crate::thir::cx::Cx;
use crate::thir::util::UserAnnotatedTyHelpers;
use itertools::Itertools;
-use rustc_ast::LitKind;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@@ -22,8 +21,7 @@ use rustc_middle::ty::{
self, AdtKind, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs, UserType,
};
use rustc_middle::{bug, span_bug};
-use rustc_span::source_map::Spanned;
-use rustc_span::{sym, Span, DUMMY_SP};
+use rustc_span::{sym, Span};
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
use tracing::{debug, info, instrument, trace};
@@ -899,14 +897,10 @@ impl<'tcx> Cx<'tcx> {
let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local());
let generics = self.tcx.generics_of(hir_id.owner);
let Some(&index) = generics.param_def_id_to_index.get(&def_id) else {
- let guar = self.tcx.dcx().has_errors().unwrap();
- // We already errored about a late bound const
-
- let lit = self
- .tcx
- .hir_arena
- .alloc(Spanned { span: DUMMY_SP, node: LitKind::Err(guar) });
- return ExprKind::Literal { lit, neg: false };
+ span_bug!(
+ expr.span,
+ "Should have already errored about late bound consts: {def_id:?}"
+ );
};
let name = self.tcx.hir().name(hir_id);
let param = ty::ParamConst::new(index, name);
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index fbc5b91460034..9aaf4b99243f5 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2773,7 +2773,14 @@ impl<'a> Parser<'a> {
let snapshot = p.create_snapshot_for_diagnostic();
let param = p.parse_param_general(req_name, first_param).or_else(|e| {
let guar = e.emit();
- let lo = p.prev_token.span;
+ // When parsing a param failed, we should check to make the span of the param
+ // not contain '(' before it.
+ // For example when parsing `*mut Self` in function `fn oof(*mut Self)`.
+ let lo = if let TokenKind::OpenDelim(Delimiter::Parenthesis) = p.prev_token.kind {
+ p.prev_token.span.shrink_to_hi()
+ } else {
+ p.prev_token.span
+ };
p.restore_snapshot(snapshot);
// Skip every token until next possible arg or end.
p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(Delimiter::Parenthesis)]);
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 2b30ca8a89478..b40a7d17eefc4 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1229,6 +1229,7 @@ symbols! {
modifiers,
module,
module_path,
+ more_maybe_bounds,
more_qualified_paths,
more_struct_aliases,
movbe_target_feature,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
index b91b755d68370..a892ce5886112 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
@@ -84,7 +84,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
}
hir::TyKind::TraitObject(bounds, ..) => {
- for bound in bounds {
+ for (bound, _) in bounds {
self.current_index.shift_in(1);
self.visit_poly_trait_ref(bound);
self.current_index.shift_out(1);
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
index ce157ff3dc8d9..e5d97976534e9 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
@@ -607,7 +607,7 @@ impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
_,
) = t.kind
{
- for ptr in poly_trait_refs {
+ for (ptr, _) in poly_trait_refs {
if Some(self.1) == ptr.trait_ref.trait_def_id() {
self.0.push(ptr.span);
}
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index 87fdc5ddff85c..89ae6f4ccab37 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -437,7 +437,7 @@ pub fn report_object_safety_error<'tcx>(
if tcx.parent_hir_node(hir_id).fn_sig().is_some() {
// Do not suggest `impl Trait` when dealing with things like super-traits.
err.span_suggestion_verbose(
- ty.span.until(trait_ref.span),
+ ty.span.until(trait_ref.0.span),
"consider using an opaque type instead",
"impl ",
Applicability::MaybeIncorrect,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 885216e62165e..d1381d24764a4 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -3040,11 +3040,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
match ty.kind {
hir::TyKind::TraitObject(traits, _, _) => {
let (span, kw) = match traits {
- [first, ..] if first.span.lo() == ty.span.lo() => {
+ [(first, _), ..] if first.span.lo() == ty.span.lo() => {
// Missing `dyn` in front of trait object.
(ty.span.shrink_to_lo(), "dyn ")
}
- [first, ..] => (ty.span.until(first.span), ""),
+ [(first, _), ..] => (ty.span.until(first.span), ""),
[] => span_bug!(ty.span, "trait object with no traits: {ty:?}"),
};
let needs_parens = traits.len() != 1;
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index c9111254082da..ae42ae3baf418 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -94,7 +94,7 @@ use crate::str;
/// ```
///
/// [str]: prim@str "str"
-#[derive(Hash)]
+#[derive(PartialEq, Eq, Hash)]
#[stable(feature = "core_c_str", since = "1.64.0")]
#[rustc_has_incoherent_inherent_impls]
#[lang = "CStr"]
@@ -104,7 +104,6 @@ use crate::str;
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
#[repr(transparent)]
-#[allow(clippy::derived_hash_with_manual_eq)]
pub struct CStr {
// FIXME: this should not be represented with a DST slice but rather with
// just a raw `c_char` along with some form of marker to make
@@ -678,15 +677,9 @@ impl CStr {
}
}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl PartialEq for CStr {
- #[inline]
- fn eq(&self, other: &CStr) -> bool {
- self.to_bytes().eq(other.to_bytes())
- }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Eq for CStr {}
+// `.to_bytes()` representations are compared instead of the inner `[c_char]`s,
+// because `c_char` is `i8` (not `u8`) on some platforms.
+// That is why this is implemented manually and not derived.
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for CStr {
#[inline]
diff --git a/library/core/tests/ffi.rs b/library/core/tests/ffi.rs
new file mode 100644
index 0000000000000..2b33fbd95f073
--- /dev/null
+++ b/library/core/tests/ffi.rs
@@ -0,0 +1 @@
+mod cstr;
diff --git a/library/core/tests/ffi/cstr.rs b/library/core/tests/ffi/cstr.rs
new file mode 100644
index 0000000000000..9bf4c21a9ab97
--- /dev/null
+++ b/library/core/tests/ffi/cstr.rs
@@ -0,0 +1,15 @@
+use core::ffi::CStr;
+
+#[test]
+fn compares_as_u8s() {
+ let a: &CStr = c"Hello!"; // Starts with ascii
+ let a_bytes: &[u8] = a.to_bytes();
+ assert!((..0b1000_0000).contains(&a_bytes[0]));
+
+ let b: &CStr = c"こんにちは!"; // Starts with non ascii
+ let b_bytes: &[u8] = b.to_bytes();
+ assert!((0b1000_0000..).contains(&b_bytes[0]));
+
+ assert_eq!(Ord::cmp(a, b), Ord::cmp(a_bytes, b_bytes));
+ assert_eq!(PartialOrd::partial_cmp(a, b), PartialOrd::partial_cmp(a_bytes, b_bytes));
+}
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 83a615fcd8be3..04aaa3f35b7ae 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -132,6 +132,7 @@ mod clone;
mod cmp;
mod const_ptr;
mod convert;
+mod ffi;
mod fmt;
mod future;
mod hash;
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 8ebcf10dd1f2e..f7ec17fde22ea 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -276,44 +276,3 @@ compat_fn_with_fallback! {
Status as u32
}
}
-
-// # Arm32 shim
-//
-// AddVectoredExceptionHandler and WSAStartup use platform-specific types.
-// However, Microsoft no longer supports thumbv7a so definitions for those targets
-// are not included in the win32 metadata. We work around that by defining them here.
-//
-// Where possible, these definitions should be kept in sync with https://docs.rs/windows-sys
-cfg_if::cfg_if! {
-if #[cfg(not(target_vendor = "uwp"))] {
- #[link(name = "kernel32")]
- extern "system" {
- pub fn AddVectoredExceptionHandler(
- first: u32,
- handler: PVECTORED_EXCEPTION_HANDLER,
- ) -> *mut c_void;
- }
- pub type PVECTORED_EXCEPTION_HANDLER = Option<
- unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32,
- >;
- #[repr(C)]
- pub struct EXCEPTION_POINTERS {
- pub ExceptionRecord: *mut EXCEPTION_RECORD,
- pub ContextRecord: *mut CONTEXT,
- }
- #[cfg(target_arch = "arm")]
- pub enum CONTEXT {}
-}}
-// WSAStartup is only redefined here so that we can override WSADATA for Arm32
-windows_targets::link!("ws2_32.dll" "system" fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32);
-#[cfg(target_arch = "arm")]
-#[repr(C)]
-pub struct WSADATA {
- pub wVersion: u16,
- pub wHighVersion: u16,
- pub szDescription: [u8; 257],
- pub szSystemStatus: [u8; 129],
- pub iMaxSockets: u16,
- pub iMaxUdpDg: u16,
- pub lpVendorInfo: PSTR,
-}
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index de4f1050e927a..afacc370c3420 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2176,6 +2176,7 @@ Windows.Win32.Networking.WinSock.WSARecv
Windows.Win32.Networking.WinSock.WSASend
Windows.Win32.Networking.WinSock.WSASERVICE_NOT_FOUND
Windows.Win32.Networking.WinSock.WSASocketW
+Windows.Win32.Networking.WinSock.WSAStartup
Windows.Win32.Networking.WinSock.WSASYSCALLFAILURE
Windows.Win32.Networking.WinSock.WSASYSNOTREADY
Windows.Win32.Networking.WinSock.WSATRY_AGAIN
@@ -2420,6 +2421,7 @@ Windows.Win32.System.Console.STD_HANDLE
Windows.Win32.System.Console.STD_INPUT_HANDLE
Windows.Win32.System.Console.STD_OUTPUT_HANDLE
Windows.Win32.System.Console.WriteConsoleW
+Windows.Win32.System.Diagnostics.Debug.AddVectoredExceptionHandler
Windows.Win32.System.Diagnostics.Debug.ARM64_NT_NEON128
Windows.Win32.System.Diagnostics.Debug.CONTEXT
Windows.Win32.System.Diagnostics.Debug.EXCEPTION_RECORD
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index 29110bde3b4c4..9f22f54819509 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -5,6 +5,7 @@ windows_targets::link!("advapi32.dll" "system" fn OpenProcessToken(processhandle
windows_targets::link!("advapi32.dll" "system" "SystemFunction036" fn RtlGenRandom(randombuffer : *mut core::ffi::c_void, randombufferlength : u32) -> BOOLEAN);
windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockExclusive(srwlock : *mut SRWLOCK));
windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockShared(srwlock : *mut SRWLOCK));
+windows_targets::link!("kernel32.dll" "system" fn AddVectoredExceptionHandler(first : u32, handler : PVECTORED_EXCEPTION_HANDLER) -> *mut core::ffi::c_void);
windows_targets::link!("kernel32.dll" "system" fn CancelIo(hfile : HANDLE) -> BOOL);
windows_targets::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE) -> BOOL);
windows_targets::link!("kernel32.dll" "system" fn CompareStringOrdinal(lpstring1 : PCWSTR, cchcount1 : i32, lpstring2 : PCWSTR, cchcount2 : i32, bignorecase : BOOL) -> COMPARESTRING_RESULT);
@@ -114,6 +115,7 @@ windows_targets::link!("ws2_32.dll" "system" fn WSAGetLastError() -> WSA_ERROR);
windows_targets::link!("ws2_32.dll" "system" fn WSARecv(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytesrecvd : *mut u32, lpflags : *mut u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
windows_targets::link!("ws2_32.dll" "system" fn WSASend(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytessent : *mut u32, dwflags : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
windows_targets::link!("ws2_32.dll" "system" fn WSASocketW(af : i32, r#type : i32, protocol : i32, lpprotocolinfo : *const WSAPROTOCOL_INFOW, g : u32, dwflags : u32) -> SOCKET);
+windows_targets::link!("ws2_32.dll" "system" fn WSAStartup(wversionrequested : u16, lpwsadata : *mut WSADATA) -> i32);
windows_targets::link!("ws2_32.dll" "system" fn accept(s : SOCKET, addr : *mut SOCKADDR, addrlen : *mut i32) -> SOCKET);
windows_targets::link!("ws2_32.dll" "system" fn bind(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32);
windows_targets::link!("ws2_32.dll" "system" fn closesocket(s : SOCKET) -> i32);
@@ -2284,6 +2286,12 @@ pub type EXCEPTION_DISPOSITION = i32;
pub const EXCEPTION_MAXIMUM_PARAMETERS: u32 = 15u32;
#[repr(C)]
#[derive(Clone, Copy)]
+pub struct EXCEPTION_POINTERS {
+ pub ExceptionRecord: *mut EXCEPTION_RECORD,
+ pub ContextRecord: *mut CONTEXT,
+}
+#[repr(C)]
+#[derive(Clone, Copy)]
pub struct EXCEPTION_RECORD {
pub ExceptionCode: NTSTATUS,
pub ExceptionFlags: u32,
@@ -2860,6 +2868,8 @@ pub type PTIMERAPCROUTINE = Option<
dwtimerhighvalue: u32,
),
>;
+pub type PVECTORED_EXCEPTION_HANDLER =
+ Option i32>;
pub type PWSTR = *mut u16;
pub const READ_CONTROL: FILE_ACCESS_RIGHTS = 131072u32;
pub const REALTIME_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 256u32;
@@ -3292,5 +3302,19 @@ pub struct XSAVE_FORMAT {
pub XmmRegisters: [M128A; 8],
pub Reserved4: [u8; 224],
}
+
+#[cfg(target_arch = "arm")]
+#[repr(C)]
+pub struct WSADATA {
+ pub wVersion: u16,
+ pub wHighVersion: u16,
+ pub szDescription: [u8; 257],
+ pub szSystemStatus: [u8; 129],
+ pub iMaxSockets: u16,
+ pub iMaxUdpDg: u16,
+ pub lpVendorInfo: PSTR,
+}
+#[cfg(target_arch = "arm")]
+pub enum CONTEXT {}
// ignore-tidy-filelength
use super::windows_targets;
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 2cd9b6fcd387e..26011926cddda 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1858,7 +1858,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
}
TyKind::Path(_) => clean_qpath(ty, cx),
TyKind::TraitObject(bounds, ref lifetime, _) => {
- let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect();
+ let bounds = bounds.iter().map(|(bound, _)| clean_poly_trait_ref(bound, cx)).collect();
let lifetime =
if !lifetime.is_elided() { Some(clean_lifetime(*lifetime, cx)) } else { None };
DynTrait(bounds, lifetime)
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 443d6189c1f77..f83101cee11c0 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -545,7 +545,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
if !lt.is_elided() {
self.unelided_trait_object_lifetime = true;
}
- for bound in bounds {
+ for (bound, _) in bounds {
self.visit_poly_trait_ref(bound);
}
},
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 07390d6f43029..41ebf59ae3aab 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -181,7 +181,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
// Iterate the bounds and add them to our seen hash
// If we haven't yet seen it, add it to the fixed traits
- for bound in bounds {
+ for (bound, _) in bounds {
let Some(def_id) = bound.trait_ref.trait_def_id() else {
continue;
};
@@ -196,9 +196,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
// If the number of unique traits isn't the same as the number of traits in the bounds,
// there must be 1 or more duplicates
if bounds.len() != unique_traits.len() {
- let mut bounds_span = bounds[0].span;
+ let mut bounds_span = bounds[0].0.span;
- for bound in bounds.iter().skip(1) {
+ for (bound, _) in bounds.iter().skip(1) {
bounds_span = bounds_span.to(bound.span);
}
diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
index 801e886261993..83cc9f2d8df23 100644
--- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
@@ -81,14 +81,17 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
// Returns true if given type is `Any` trait.
fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool {
- if let TyKind::TraitObject(traits, ..) = t.kind
- && !traits.is_empty()
- && let Some(trait_did) = traits[0].trait_ref.trait_def_id()
- // Only Send/Sync can be used as additional traits, so it is enough to
- // check only the first trait.
- && cx.tcx.is_diagnostic_item(sym::Any, trait_did)
- {
- return true;
+ if let TyKind::TraitObject(traits, ..) = t.kind {
+ return traits
+ .iter()
+ .any(|(bound, _)| {
+ if let Some(trait_did) = bound.trait_ref.trait_def_id()
+ && cx.tcx.is_diagnostic_item(sym::Any, trait_did)
+ {
+ return true;
+ }
+ false
+ });
}
false
diff --git a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
index b6e765d7c3937..7fcfd5c8f350d 100644
--- a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
@@ -55,6 +55,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
TyKind::TraitObject(param_bounds, _, _) => {
let has_lifetime_parameters = param_bounds.iter().any(|bound| {
bound
+ .0
.bound_generic_params
.iter()
.any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs
index fd21e7a86b002..90fce2b675ad7 100644
--- a/src/tools/generate-windows-sys/src/main.rs
+++ b/src/tools/generate-windows-sys/src/main.rs
@@ -4,6 +4,24 @@ use std::fs;
use std::io::{Read, Seek, SeekFrom, Write};
use std::path::PathBuf;
+/// 32-bit ARM is not supported by Microsoft so ARM types are not generated.
+/// Therefore we need to inject a few types to make the bindings work.
+const ARM32_SHIM: &str = r#"
+#[cfg(target_arch = "arm")]
+#[repr(C)]
+pub struct WSADATA {
+ pub wVersion: u16,
+ pub wHighVersion: u16,
+ pub szDescription: [u8; 257],
+ pub szSystemStatus: [u8; 129],
+ pub iMaxSockets: u16,
+ pub iMaxUdpDg: u16,
+ pub lpVendorInfo: PSTR,
+}
+#[cfg(target_arch = "arm")]
+pub enum CONTEXT {}
+"#;
+
fn main() -> Result<(), Box> {
let mut path: PathBuf =
env::args_os().nth(1).expect("a path to the rust repository is required").into();
@@ -16,6 +34,7 @@ fn main() -> Result<(), Box> {
println!("{info}");
let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?;
+ f.write_all(ARM32_SHIM.as_bytes())?;
writeln!(&mut f, "// ignore-tidy-filelength")?;
writeln!(&mut f, "use super::windows_targets;")?;
diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs
new file mode 100644
index 0000000000000..4541499b7c7de
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs
@@ -0,0 +1,17 @@
+#![feature(auto_traits)]
+
+trait Trait1 {}
+auto trait Trait2 {}
+trait Trait3: ?Trait1 {}
+//~^ ERROR `?Trait` is not permitted in supertraits
+trait Trait4 where Self: ?Trait1 {}
+//~^ ERROR ?Trait` bounds are only permitted at the point where a type parameter is declared
+
+fn foo(_: Box) {}
+//~^ ERROR `?Trait` is not permitted in trait object types
+fn bar(_: T) {}
+//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr
new file mode 100644
index 0000000000000..2b7a353020adb
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr
@@ -0,0 +1,53 @@
+error[E0658]: `?Trait` is not permitted in supertraits
+ --> $DIR/feature-gate-more-maybe-bounds.rs:5:15
+ |
+LL | trait Trait3: ?Trait1 {}
+ | ^^^^^^^
+ |
+ = note: traits are `?Trait1` by default
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `?Trait` is not permitted in trait object types
+ --> $DIR/feature-gate-more-maybe-bounds.rs:10:28
+ |
+LL | fn foo(_: Box) {}
+ | ^^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
+ --> $DIR/feature-gate-more-maybe-bounds.rs:7:26
+ |
+LL | trait Trait4 where Self: ?Trait1 {}
+ | ^^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0203]: type parameter has more than one relaxed default bound, only one is supported
+ --> $DIR/feature-gate-more-maybe-bounds.rs:12:11
+ |
+LL | fn bar(_: T) {}
+ | ^^^^^^^ ^^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+ --> $DIR/feature-gate-more-maybe-bounds.rs:12:11
+ |
+LL | fn bar(_: T) {}
+ | ^^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+ --> $DIR/feature-gate-more-maybe-bounds.rs:12:21
+ |
+LL | fn bar(_: T) {}
+ | ^^^^^^^
+
+error: aborting due to 4 previous errors; 2 warnings emitted
+
+Some errors have detailed explanations: E0203, E0658.
+For more information about an error, try `rustc --explain E0203`.
diff --git a/tests/ui/maybe-bounds.stderr b/tests/ui/maybe-bounds.stderr
index 1d823b6acb283..230d11fd0ae66 100644
--- a/tests/ui/maybe-bounds.stderr
+++ b/tests/ui/maybe-bounds.stderr
@@ -1,22 +1,31 @@
-error: `?Trait` is not permitted in supertraits
+error[E0658]: `?Trait` is not permitted in supertraits
--> $DIR/maybe-bounds.rs:1:11
|
LL | trait Tr: ?Sized {}
| ^^^^^^
|
= note: traits are `?Sized` by default
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bounds.rs:4:20
|
LL | type A1 = dyn Tr + (?Sized);
| ^^^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bounds.rs:6:28
|
LL | type A2 = dyn for<'a> Tr + (?Sized);
| ^^^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 3 previous errors
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/parser/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr
index 3134746b930ac..ff32b173d4941 100644
--- a/tests/ui/parser/trait-object-trait-parens.stderr
+++ b/tests/ui/parser/trait-object-trait-parens.stderr
@@ -1,20 +1,29 @@
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/trait-object-trait-parens.rs:8:24
|
LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
| ^^^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/trait-object-trait-parens.rs:13:16
|
LL | let _: Box Trait<'a>) + (Obj)>;
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/trait-object-trait-parens.rs:18:44
|
LL | let _: Box Trait<'a> + (Obj) + (?Sized)>;
| ^^^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/trait-object-trait-parens.rs:8:16
@@ -91,4 +100,5 @@ LL | let _: Box Trait<'a> + (Obj) + (?Sized)>;
error: aborting due to 6 previous errors; 3 warnings emitted
-For more information about this error, try `rustc --explain E0225`.
+Some errors have detailed explanations: E0225, E0658.
+For more information about an error, try `rustc --explain E0225`.
diff --git a/tests/ui/suggestions/suggest-add-self-issue-128042.rs b/tests/ui/suggestions/suggest-add-self-issue-128042.rs
new file mode 100644
index 0000000000000..f94d166c4967a
--- /dev/null
+++ b/tests/ui/suggestions/suggest-add-self-issue-128042.rs
@@ -0,0 +1,12 @@
+struct Thing {
+ state: u8,
+}
+
+impl Thing {
+ fn oof(*mut Self) { //~ ERROR expected parameter name, found `*`
+ self.state = 1;
+ //~^ ERROR expected value, found module `self`
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/suggest-add-self-issue-128042.stderr b/tests/ui/suggestions/suggest-add-self-issue-128042.stderr
new file mode 100644
index 0000000000000..49ac15632501a
--- /dev/null
+++ b/tests/ui/suggestions/suggest-add-self-issue-128042.stderr
@@ -0,0 +1,22 @@
+error: expected parameter name, found `*`
+ --> $DIR/suggest-add-self-issue-128042.rs:6:12
+ |
+LL | fn oof(*mut Self) {
+ | ^ expected parameter name
+
+error[E0424]: expected value, found module `self`
+ --> $DIR/suggest-add-self-issue-128042.rs:7:9
+ |
+LL | fn oof(*mut Self) {
+ | --- this function doesn't have a `self` parameter
+LL | self.state = 1;
+ | ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+ |
+help: add a `self` receiver parameter to make the associated `fn` a method
+ |
+LL | fn oof(&self, *mut Self) {
+ | ++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0424`.
diff --git a/tests/ui/traits/maybe-polarity-pass.rs b/tests/ui/traits/maybe-polarity-pass.rs
new file mode 100644
index 0000000000000..075a0d8dcac4d
--- /dev/null
+++ b/tests/ui/traits/maybe-polarity-pass.rs
@@ -0,0 +1,27 @@
+//@ check-pass
+
+#![feature(auto_traits)]
+#![feature(more_maybe_bounds)]
+#![feature(negative_impls)]
+
+trait Trait1 {}
+auto trait Trait2 {}
+
+trait Trait3 : ?Trait1 {}
+trait Trait4 where Self: Trait1 {}
+
+fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}
+fn bar(_: &T) {}
+//~^ WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+
+struct S;
+impl !Trait2 for S {}
+impl Trait1 for S {}
+impl Trait3 for S {}
+
+fn main() {
+ foo(Box::new(S));
+ bar(&S);
+}
diff --git a/tests/ui/traits/maybe-polarity-pass.stderr b/tests/ui/traits/maybe-polarity-pass.stderr
new file mode 100644
index 0000000000000..09ed52f5b0dd7
--- /dev/null
+++ b/tests/ui/traits/maybe-polarity-pass.stderr
@@ -0,0 +1,20 @@
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+ --> $DIR/maybe-polarity-pass.rs:14:20
+ |
+LL | fn bar(_: &T) {}
+ | ^^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+ --> $DIR/maybe-polarity-pass.rs:14:30
+ |
+LL | fn bar(_: &T) {}
+ | ^^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+ --> $DIR/maybe-polarity-pass.rs:14:40
+ |
+LL | fn bar(_: &T) {}
+ | ^^^^^^^
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/traits/wf-object/maybe-bound.stderr b/tests/ui/traits/wf-object/maybe-bound.stderr
index 2fe3f0fc39f40..be7afabd0d01d 100644
--- a/tests/ui/traits/wf-object/maybe-bound.stderr
+++ b/tests/ui/traits/wf-object/maybe-bound.stderr
@@ -1,32 +1,48 @@
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bound.rs:5:15
|
LL | type _0 = dyn ?Sized + Foo;
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bound.rs:8:21
|
LL | type _1 = dyn Foo + ?Sized;
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bound.rs:11:21
|
LL | type _2 = dyn Foo + ?Sized + ?Sized;
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bound.rs:11:30
|
LL | type _2 = dyn Foo + ?Sized + ?Sized;
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bound.rs:15:15
|
LL | type _3 = dyn ?Sized + Foo;
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 5 previous errors
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/wf-object/only-maybe-bound.stderr b/tests/ui/traits/wf-object/only-maybe-bound.stderr
index cbc41feec1e8c..26269476eaaee 100644
--- a/tests/ui/traits/wf-object/only-maybe-bound.stderr
+++ b/tests/ui/traits/wf-object/only-maybe-bound.stderr
@@ -1,8 +1,11 @@
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/only-maybe-bound.rs:3:15
|
LL | type _0 = dyn ?Sized;
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0224]: at least one trait is required for an object type
--> $DIR/only-maybe-bound.rs:3:11
@@ -12,4 +15,5 @@ LL | type _0 = dyn ?Sized;
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0224`.
+Some errors have detailed explanations: E0224, E0658.
+For more information about an error, try `rustc --explain E0224`.
diff --git a/tests/ui/unsized/maybe-bounds-where.stderr b/tests/ui/unsized/maybe-bounds-where.stderr
index 683bd387bb292..f785126166781 100644
--- a/tests/ui/unsized/maybe-bounds-where.stderr
+++ b/tests/ui/unsized/maybe-bounds-where.stderr
@@ -1,32 +1,47 @@
-error: `?Trait` bounds are only permitted at the point where a type parameter is declared
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:1:28
|
LL | struct S1(T) where (T): ?Sized;
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` bounds are only permitted at the point where a type parameter is declared
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:4:27
|
LL | struct S2(T) where u8: ?Sized;
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` bounds are only permitted at the point where a type parameter is declared
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:7:35
|
LL | struct S3(T) where &'static T: ?Sized;
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` bounds are only permitted at the point where a type parameter is declared
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:12:34
|
LL | struct S4(T) where for<'a> T: ?Trait<'a>;
| ^^^^^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-error: `?Trait` bounds are only permitted at the point where a type parameter is declared
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:21:21
|
LL | fn f() where T: ?Sized {}
| ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bounds-where.rs:12:34
@@ -39,6 +54,9 @@ error[E0203]: type parameter has more than one relaxed default bound, only one i
|
LL | struct S5(*const T) where T: ?Trait<'static> + ?Sized;
| ^^^^^^^^^^^^^^^ ^^^^^^
+ |
+ = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bounds-where.rs:16:33
@@ -48,4 +66,5 @@ LL | struct S5(*const T) where T: ?Trait<'static> + ?Sized;
error: aborting due to 6 previous errors; 2 warnings emitted
-For more information about this error, try `rustc --explain E0203`.
+Some errors have detailed explanations: E0203, E0658.
+For more information about an error, try `rustc --explain E0203`.