authorbors <bors@rust-lang.org> 2026-07-05 07:24:27 UTC
committerbors <bors@rust-lang.org> 2026-07-05 07:24:27 UTC
log4eb62535fc12dd1a63fd43a4173e224e79313c4d
tree2df8f5575671e2c13e2ca7aebf6393ee447f143a
parentea088e0a3dd50c494b4589c3c121d7469dceec8f
parent3755fd95ad3146b1565b342c57073d5341ae664c

Auto merge of #158795 - JonathanBrouwer:rollup-vhfdJ4m, r=JonathanBrouwer

Rollup of 21 pull requests Successful merges: - rust-lang/rust#158100 (Emit retags in codegen to support BorrowSanitizer (part 4)) - rust-lang/rust#158494 (Improve E0277 diagnostics for conditionally implemented traits) - rust-lang/rust#158606 (use ProjectionPredicate instead of AliasRelate) - rust-lang/rust#158627 (Simplify option-iterator flattening in the compiler) - rust-lang/rust#158658 (Update LLVM submodule) - rust-lang/rust#158665 (Revert "Remove redundant dyn-compatibility check.") - rust-lang/rust#158021 (Remove old MinGW workaround) - rust-lang/rust#158473 (Add `riscv32imfc-unknown-none-elf` bare-metal target) - rust-lang/rust#158549 (process::exec: using appropriate exit code on vxworks.) - rust-lang/rust#158585 (Improve diagnostic for too many super keywords) - rust-lang/rust#158637 (hir_ty_lowering: avoid self type lookup for inherent aliases) - rust-lang/rust#158651 (ptr doc: reduce use of unsafe block to where needed) - rust-lang/rust#158669 (Remove `src/tools/test-float-parse/Cargo.lock`) - rust-lang/rust#158674 (library: Polish transmute's `split_at_stdlib` example) - rust-lang/rust#158677 (Add extra splat tests) - rust-lang/rust#158680 (Avoid ICE for `NonZero<char>` in improper_ctypes) - rust-lang/rust#158681 (Remove unnecessary `Hash` derives from MIR types) - rust-lang/rust#158682 (Avoid delayed bug for disabled on_type_error arguments) - rust-lang/rust#158684 (Add missing generic test coverage for ```#[splat]```) - rust-lang/rust#158687 (Streamline `MacEager`) - rust-lang/rust#158688 (Cleanup attribute docs and add links to other mentioned attributes)

143 files changed, 1395 insertions(+), 931 deletions(-)

compiler/rustc_ast_passes/src/feature_gate.rs+8-8
......@@ -466,7 +466,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
466466 let spans = sess.psess.gated_spans.spans.borrow();
467467 macro_rules! gate_all {
468468 ($feature:ident, $explain:literal $(, $help:literal)?) => {
469 for &span in spans.get(&sym::$feature).into_iter().flatten() {
469 for &span in spans.get(&sym::$feature).into_flat_iter() {
470470 gate!(visitor, $feature, span, $explain $(, $help)?);
471471 }
472472 };
......@@ -527,13 +527,13 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
527527 );
528528
529529 // `associated_const_equality` will be stabilized as part of `min_generic_const_args`.
530 for &span in spans.get(&sym::associated_const_equality).into_iter().flatten() {
530 for &span in spans.get(&sym::associated_const_equality).into_flat_iter() {
531531 gate!(visitor, min_generic_const_args, span, "associated const equality is incomplete");
532532 }
533533
534534 // `mgca_type_const_syntax` is part of `min_generic_const_args` so if
535535 // either or both are enabled we don't need to emit a feature error.
536 for &span in spans.get(&sym::mgca_type_const_syntax).into_iter().flatten() {
536 for &span in spans.get(&sym::mgca_type_const_syntax).into_flat_iter() {
537537 if visitor.features.min_generic_const_args()
538538 || visitor.features.mgca_type_const_syntax()
539539 || span.allows_unstable(sym::min_generic_const_args)
......@@ -561,13 +561,13 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
561561 // it does **not** mean "`T` doesn't implement `Bound` (positively or negatively)"!
562562 // The latter would be a SemVer hazard!
563563 if !sess.opts.unstable_opts.internal_testing_features || !visitor.features.negative_bounds() {
564 for &span in spans.get(&sym::negative_bounds).into_iter().flatten() {
564 for &span in spans.get(&sym::negative_bounds).into_flat_iter() {
565565 sess.dcx().emit_err(diagnostics::NegativeBoundUnsupported { span });
566566 }
567567 }
568568
569569 if !visitor.features.never_patterns() {
570 for &span in spans.get(&sym::never_patterns).into_iter().flatten() {
570 for &span in spans.get(&sym::never_patterns).into_flat_iter() {
571571 if span.allows_unstable(sym::never_patterns) {
572572 continue;
573573 }
......@@ -585,7 +585,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
585585 }
586586
587587 // Yield exprs can be enabled either by `yield_expr`, by `coroutines` or by `gen_blocks`.
588 for &span in spans.get(&sym::yield_expr).into_iter().flatten() {
588 for &span in spans.get(&sym::yield_expr).into_flat_iter() {
589589 if (!visitor.features.coroutines() && !span.allows_unstable(sym::coroutines))
590590 && (!visitor.features.gen_blocks() && !span.allows_unstable(sym::gen_blocks))
591591 && (!visitor.features.yield_expr() && !span.allows_unstable(sym::yield_expr))
......@@ -607,7 +607,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
607607
608608 macro_rules! soft_gate_all_legacy_dont_use {
609609 ($feature:ident, $explain:literal) => {
610 for &span in spans.get(&sym::$feature).into_iter().flatten() {
610 for &span in spans.get(&sym::$feature).into_flat_iter() {
611611 if !visitor.features.$feature() && !span.allows_unstable(sym::$feature) {
612612 feature_warn(&visitor.sess, sym::$feature, span, $explain);
613613 }
......@@ -625,7 +625,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
625625 soft_gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable");
626626 // tidy-alphabetical-end
627627
628 for &span in spans.get(&sym::min_specialization).into_iter().flatten() {
628 for &span in spans.get(&sym::min_specialization).into_flat_iter() {
629629 if !visitor.features.specialization()
630630 && !visitor.features.min_specialization()
631631 && !span.allows_unstable(sym::specialization)
compiler/rustc_ast_passes/src/lib.rs+1
......@@ -6,6 +6,7 @@
66#![feature(deref_patterns)]
77#![feature(iter_intersperse)]
88#![feature(iter_is_partitioned)]
9#![feature(option_into_flat_iter)]
910// tidy-alphabetical-end
1011
1112pub mod ast_validation;
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_type_error.rs+2
......@@ -18,6 +18,8 @@ pub(crate) struct OnTypeErrorParser {
1818impl OnTypeErrorParser {
1919 fn parse<'sess>(&mut self, cx: &mut AcceptContext<'_, 'sess>, args: &ArgParser, mode: Mode) {
2020 if !cx.features().diagnostic_on_type_error() {
21 // `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
22 args.ignore_args();
2123 return;
2224 }
2325
compiler/rustc_borrowck/src/dataflow.rs+2-3
......@@ -476,9 +476,8 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
476476 .borrow_set
477477 .local_map
478478 .get(&place.local)
479 .into_iter()
480 .flat_map(|bs| bs.iter())
481 .copied();
479 .map(|bs| bs.iter().copied())
480 .into_flat_iter();
482481
483482 // If the borrowed place is a local with no projections, all other borrows of this
484483 // local must conflict. This is purely an optimization so we don't have to call
compiler/rustc_borrowck/src/lib.rs+1
......@@ -7,6 +7,7 @@
77#![feature(file_buffered)]
88#![feature(negative_impls)]
99#![feature(never_type)]
10#![feature(option_into_flat_iter)]
1011#![feature(rustc_attrs)]
1112#![feature(stmt_expr_attributes)]
1213#![feature(try_blocks)]
compiler/rustc_borrowck/src/polonius/constraints.rs+2-2
......@@ -152,7 +152,7 @@ impl LocalizedConstraintGraph {
152152 // The physical edges present at this node are:
153153 //
154154 // 1. the typeck edges that flow from region to region *at this point*.
155 for &succ in self.edges.get(&node).into_iter().flatten() {
155 for &succ in self.edges.get(&node).into_flat_iter() {
156156 let succ = LocalizedNode { region: succ, point: node.point };
157157 successor_found(succ);
158158 }
......@@ -229,7 +229,7 @@ impl LocalizedConstraintGraph {
229229 }
230230
231231 // And finally, we have the logical edges, materialized at this point.
232 for &logical_succ in self.logical_edges.get(&node.region).into_iter().flatten() {
232 for &logical_succ in self.logical_edges.get(&node.region).into_flat_iter() {
233233 let succ = LocalizedNode { region: logical_succ, point: node.point };
234234 successor_found(succ);
235235 }
compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs+1-1
......@@ -49,7 +49,7 @@ pub(super) fn apply_member_constraints<'tcx>(
4949 rcx.scc_values.add_region(scc_a, scc_b);
5050 }
5151
52 for defining_use in member_constraints.get(&scc_a).into_iter().flatten() {
52 for defining_use in member_constraints.get(&scc_a).into_flat_iter() {
5353 apply_member_constraint(rcx, scc_a, &defining_use.arg_regions);
5454 }
5555 }
compiler/rustc_borrowck/src/region_infer/values.rs+6-6
......@@ -178,7 +178,7 @@ impl LivenessValues {
178178
179179 /// Returns an iterator of all the points where `region` is live.
180180 fn live_points(&self, region: RegionVid) -> impl Iterator<Item = PointIndex> {
181 self.point_liveness(region).into_iter().flat_map(|set| set.iter())
181 self.point_liveness(region).map(|set| set.iter()).into_flat_iter()
182182 }
183183
184184 /// For debugging purposes, returns a pretty-printed string of the points where the `region` is
......@@ -348,13 +348,13 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> {
348348 pub(crate) fn locations_outlived_by(&self, r: N) -> impl Iterator<Item = Location> {
349349 self.points
350350 .row(r)
351 .into_iter()
352 .flat_map(move |set| set.iter().map(move |p| self.location_map.to_location(p)))
351 .map(move |set| set.iter().map(move |p| self.location_map.to_location(p)))
352 .into_flat_iter()
353353 }
354354
355355 /// Returns just the universal regions that are contained in a given region's value.
356356 pub(crate) fn universal_regions_outlived_by(&self, r: N) -> impl Iterator<Item = RegionVid> {
357 self.free_regions.row(r).into_iter().flat_map(|set| set.iter())
357 self.free_regions.row(r).map(|set| set.iter()).into_flat_iter()
358358 }
359359
360360 /// Returns all the elements contained in a given region's value.
......@@ -364,8 +364,8 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> {
364364 ) -> impl Iterator<Item = ty::PlaceholderRegion<'tcx>> {
365365 self.placeholders
366366 .row(r)
367 .into_iter()
368 .flat_map(|set| set.iter())
367 .map(|set| set.iter())
368 .into_flat_iter()
369369 .map(move |p| self.placeholder_indices.lookup_placeholder(p))
370370 }
371371
compiler/rustc_borrowck/src/type_check/mod.rs+1-1
......@@ -928,7 +928,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
928928 self.super_local_decl(local, local_decl);
929929
930930 for user_ty in
931 local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections)
931 local_decl.user_ty.as_deref().map(UserTypeProjections::projections).into_flat_iter()
932932 {
933933 let span = self.user_type_annotations[user_ty.base].span;
934934
compiler/rustc_borrowck/src/type_check/relate_tys.rs+2-22
......@@ -597,27 +597,7 @@ impl<'b, 'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for NllTypeRelating<'_
597597 );
598598 }
599599
600 fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
601 self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
602 ty::Covariant => ty::PredicateKind::AliasRelate(
603 a.into(),
604 b.into(),
605 ty::AliasRelationDirection::Subtype,
606 ),
607 // a :> b is b <: a
608 ty::Contravariant => ty::PredicateKind::AliasRelate(
609 b.into(),
610 a.into(),
611 ty::AliasRelationDirection::Subtype,
612 ),
613 ty::Invariant => ty::PredicateKind::AliasRelate(
614 a.into(),
615 b.into(),
616 ty::AliasRelationDirection::Equate,
617 ),
618 ty::Bivariant => {
619 unreachable!("cannot defer an alias-relate goal with Bivariant variance (yet?)")
620 }
621 })]);
600 fn ambient_variance(&self) -> ty::Variance {
601 self.ambient_variance
622602 }
623603}
compiler/rustc_codegen_ssa/src/assert_module_sources.rs+1-2
......@@ -90,8 +90,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
9090 fn check_attrs(&mut self, attrs: &[hir::Attribute]) {
9191 for &(span, cgu_fields) in find_attr!(attrs,
9292 RustcCguTestAttr(e) => e)
93 .into_iter()
94 .flatten()
93 .into_flat_iter()
9594 {
9695 let (expected_reuse, comp_kind) = match cgu_fields {
9796 CguFields::PartitionReused { .. } => (CguReuse::PreLto, ComparisonKind::AtLeast),
compiler/rustc_codegen_ssa/src/back/link.rs+3-5
......@@ -1091,9 +1091,7 @@ fn link_natively(
10911091 let get_objects = |objects: &CrtObjects, kind| {
10921092 objects
10931093 .get(&kind)
1094 .iter()
1095 .copied()
1096 .flatten()
1094 .into_flat_iter()
10971095 .map(|obj| {
10981096 get_object_file_path(sess, obj, self_contained_crt_objects).into_os_string()
10991097 })
......@@ -2073,7 +2071,7 @@ fn add_pre_link_objects(
20732071 } else {
20742072 &empty
20752073 };
2076 for obj in objects.get(&link_output_kind).iter().copied().flatten() {
2074 for obj in objects.get(&link_output_kind).into_flat_iter() {
20772075 cmd.add_object(&get_object_file_path(sess, obj, self_contained));
20782076 }
20792077}
......@@ -2090,7 +2088,7 @@ fn add_post_link_objects(
20902088 } else {
20912089 &sess.target.post_link_objects
20922090 };
2093 for obj in objects.get(&link_output_kind).iter().copied().flatten() {
2091 for obj in objects.get(&link_output_kind).into_flat_iter() {
20942092 cmd.add_object(&get_object_file_path(sess, obj, self_contained));
20952093 }
20962094}
compiler/rustc_codegen_ssa/src/lib.rs+1
......@@ -2,6 +2,7 @@
22#![feature(deref_patterns)]
33#![feature(file_buffered)]
44#![feature(negative_impls)]
5#![feature(option_into_flat_iter)]
56#![feature(string_from_utf8_lossy_owned)]
67#![feature(trait_alias)]
78#![feature(try_blocks)]
compiler/rustc_codegen_ssa/src/mir/operand.rs+49
......@@ -718,6 +718,34 @@ impl<'a, 'tcx, V: CodegenObject> OperandRefBuilder<'tcx, V> {
718718 OperandRefBuilder { val, layout }
719719 }
720720
721 /// Creates an initialized builder for updating an existing `operand`.
722 ///
723 /// ICEs for [`BackendRepr::Memory`] types (other than ZSTs), which use
724 /// which use [`OperandValue::Ref`]. In this case, updates should be
725 /// performed by writing into the place
726 pub(super) fn from_existing(operand: OperandRef<'tcx, V>) -> Self {
727 let layout = operand.layout;
728 let val = match (operand.val, layout.backend_repr) {
729 (OperandValue::ZeroSized, _) => OperandValueBuilder::ZeroSized,
730 (OperandValue::Immediate(v), BackendRepr::Scalar(_)) => {
731 OperandValueBuilder::Immediate(Either::Left(v))
732 }
733 (OperandValue::Immediate(v), BackendRepr::SimdVector { .. }) => {
734 OperandValueBuilder::Vector(Either::Left(v))
735 }
736 (OperandValue::Pair(a, b), BackendRepr::ScalarPair(_, _)) => {
737 OperandValueBuilder::Pair(Either::Left(a), Either::Left(b))
738 }
739 (_, BackendRepr::Memory { .. }) => {
740 bug!("Cannot use non-ZST Memory-ABI type in operand builder: {layout:?}");
741 }
742 _ => {
743 bug!("Operand cannot be used with `from_existing`: {operand:?}")
744 }
745 };
746 OperandRefBuilder { val, layout }
747 }
748
721749 pub(super) fn insert_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
722750 &mut self,
723751 bx: &mut Bx,
......@@ -829,6 +857,27 @@ impl<'a, 'tcx, V: CodegenObject> OperandRefBuilder<'tcx, V> {
829857 }
830858 }
831859
860 /// Replaces the current immediate value at the offset `offset`
861 /// with the value `imm`. A value must already be present.
862 ///
863 /// This is used along with [`Self::from_existing`] to perform in-place updates
864 /// of any operand.
865 pub(super) fn update_imm(&mut self, offset: Size, imm: V) {
866 let is_zero_offset = offset == Size::ZERO;
867 match &mut self.val {
868 OperandValueBuilder::Immediate(val @ Either::Left(_)) if is_zero_offset => {
869 *val = Either::Left(imm);
870 }
871 OperandValueBuilder::Pair(fst @ Either::Left(_), _) if is_zero_offset => {
872 *fst = Either::Left(imm);
873 }
874 OperandValueBuilder::Pair(_, snd @ Either::Left(_)) if !is_zero_offset => {
875 *snd = Either::Left(imm);
876 }
877 _ => bug!("Tried to update {imm:?} at offset {offset:?} of {self:?}"),
878 }
879 }
880
832881 /// After having set all necessary fields, this converts the builder back
833882 /// to the normal `OperandRef`.
834883 ///
compiler/rustc_codegen_ssa/src/mir/retag.rs+185-21
......@@ -4,19 +4,20 @@
44//! of an assignment. The first step to retagging is to generate a [`RetagPlan`], which
55//! describes which pointers within the place or operand can be retagged.
66
7#![allow(unused)]
8use rustc_abi::{BackendRepr, FieldIdx, FieldsShape, VariantIdx, Variants};
7use rustc_abi::{FieldIdx, FieldsShape, Size, VariantIdx, Variants};
98use rustc_ast::Mutability;
109use rustc_data_structures::fx::FxIndexMap;
1110use rustc_middle::mir::{Rvalue, WithRetag};
1211use rustc_middle::ty;
1312use rustc_middle::ty::layout::TyAndLayout;
1413
15use crate::RetagInfo;
1614use crate::mir::FunctionCx;
17use crate::mir::operand::OperandRef;
15use crate::mir::operand::{OperandRef, OperandRefBuilder, OperandValue};
1816use crate::mir::place::PlaceRef;
19use crate::traits::BuilderMethods;
17use crate::traits::{
18 BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, LayoutTypeCodegenMethods,
19};
20use crate::{RetagFlags, RetagInfo};
2021
2122pub(crate) fn rvalue_needs_retag(rvalue: &Rvalue<'_>) -> bool {
2223 // `Ref` has its own internal retagging
......@@ -58,12 +59,6 @@ impl<'a, 'tcx, V> RetagPlan<V> {
5859 if layout.is_sized() && layout.size < bx.tcx().data_layout.pointer_size() {
5960 return None;
6061 }
61 // SIMD vectors may only contain raw pointers, integers, and floating point values,
62 // which do not need to be retagged.
63 if matches!(layout.backend_repr, BackendRepr::SimdVector { .. }) {
64 return None;
65 }
66
6762 // Check the type of this value to see what to do with it (retag, or recurse).
6863 match layout.ty.kind() {
6964 &ty::Ref(_, pointee, mt) => {
......@@ -168,12 +163,42 @@ impl<'a, 'tcx, V> RetagPlan<V> {
168163 /// to types that are entirely covered by `UnsafePinned`, for which retags
169164 /// are a no-op.
170165 fn emit_retag<Bx: BuilderMethods<'a, 'tcx>>(
171 _bx: &mut Bx,
172 _pointee_layout: TyAndLayout<'tcx>,
173 _ptr_kind: Option<Mutability>,
174 _is_fn_entry: bool,
166 bx: &mut Bx,
167 pointee_layout: TyAndLayout<'tcx>,
168 ptr_kind: Option<Mutability>,
169 is_fn_entry: bool,
175170 ) -> Option<RetagPlan<Bx::Value>> {
176 None
171 let tcx = bx.tcx();
172
173 let pointee_ty = pointee_layout.ty;
174
175 let is_mutable = matches!(ptr_kind, Some(Mutability::Mut) | None);
176 let is_unpin = pointee_ty.is_unpin(tcx, bx.typing_env());
177 let is_freeze = pointee_ty.is_freeze(tcx, bx.typing_env());
178 let is_box = ptr_kind.is_none();
179
180 // `&mut !Unpin` is not protected
181 let is_protected = is_fn_entry && (!is_mutable || is_unpin);
182
183 if is_mutable && !is_unpin {
184 return None;
185 }
186
187 let im_layout = bx.const_null(bx.type_ptr());
188 let pin_layout = bx.const_null(bx.type_ptr());
189
190 let mut flags = RetagFlags::empty();
191 flags.set(RetagFlags::IS_PROTECTED, is_protected);
192 flags.set(RetagFlags::IS_MUTABLE, is_mutable);
193 flags.set(RetagFlags::IS_FREEZE, is_freeze);
194 flags.set(RetagFlags::IS_BOX, is_box);
195
196 Some(RetagPlan::EmitRetag(RetagInfo {
197 size: pointee_layout.size,
198 im_layout,
199 pin_layout,
200 flags,
201 }))
177202 }
178203}
179204
......@@ -181,19 +206,158 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
181206 /// Retags the pointers within an [`OperandRef`].
182207 pub(crate) fn codegen_retag_operand(
183208 &mut self,
184 _bx: &mut Bx,
209 bx: &mut Bx,
185210 operand: OperandRef<'tcx, Bx::Value>,
186 _is_fn_entry: bool,
211 is_fn_entry: bool,
187212 ) -> OperandRef<'tcx, Bx::Value> {
213 if let OperandValue::Ref(place_ref) = operand.val {
214 let place_ref = place_ref.with_type(operand.layout);
215 self.codegen_retag_place(bx, place_ref, is_fn_entry);
216 } else if let Some(plan) = RetagPlan::<Bx::Value>::build(bx, operand.layout, is_fn_entry) {
217 let mut builder = OperandRefBuilder::from_existing(operand);
218 self.retag_operand(bx, &plan, operand, &mut builder, Size::ZERO);
219 return builder.build(bx.cx());
220 }
188221 operand
189222 }
190223
191224 /// Retags the pointers within a [`PlaceRef`].
192225 pub(crate) fn codegen_retag_place(
193226 &mut self,
194 _bx: &mut Bx,
195 _place_ref: PlaceRef<'tcx, Bx::Value>,
196 _is_fn_entry: bool,
227 bx: &mut Bx,
228 place_ref: PlaceRef<'tcx, Bx::Value>,
229 is_fn_entry: bool,
197230 ) {
231 if let Some(plan) = RetagPlan::<Bx::Value>::build(bx, place_ref.layout, is_fn_entry) {
232 self.retag_place(bx, &plan, place_ref);
233 }
234 }
235
236 fn retag_operand(
237 &mut self,
238 bx: &mut Bx,
239 plan: &RetagPlan<Bx::Value>,
240 curr_operand: OperandRef<'tcx, Bx::Value>,
241 builder: &mut OperandRefBuilder<'tcx, Bx::Value>,
242 offset: Size,
243 ) {
244 match plan {
245 RetagPlan::EmitRetag(info) => {
246 let (pointer, _) = curr_operand.val.pointer_parts();
247 let retagged_pointer = bx.retag_reg(pointer, info);
248 builder.update_imm(offset, retagged_pointer);
249 }
250 RetagPlan::Recurse { field_plans, variant_plans } => {
251 let layout = curr_operand.layout;
252 for (ix, plan) in field_plans {
253 let inner_offset = layout.fields.offset(ix.as_usize());
254 let field_offset = offset + inner_offset;
255
256 let field_layout = curr_operand.layout.field(bx, ix.index());
257 // Part of https://github.com/rust-lang/compiler-team/issues/838
258 if !bx.is_backend_ref(curr_operand.layout) && bx.is_backend_ref(field_layout) {
259 // FIXME: support vector types, requires insert_element as part of cg-ssa
260 } else {
261 let field_operand = curr_operand.extract_field(self, bx, ix.as_usize());
262 self.retag_operand(bx, &plan, field_operand, builder, field_offset);
263 }
264 }
265
266 if !variant_plans.is_empty() {
267 let discr_ty = layout.ty.discriminant_ty(bx.tcx());
268 let discr_val = curr_operand.codegen_get_discr(self, bx, discr_ty);
269
270 if let Some(val) = bx.const_to_opt_u128(discr_val, false) {
271 let ix = VariantIdx::from_usize(val as usize);
272 if let Some(plan) = variant_plans.get(&ix) {
273 let mut variant_op = curr_operand;
274 variant_op.layout = curr_operand.layout.for_variant(bx, ix);
275
276 self.retag_operand(bx, plan, variant_op, builder, offset);
277 }
278 } else {
279 // We create a temporary place to store the operand, because its value will differ
280 // depending on the variant that we have.
281 let scratch = PlaceRef::alloca(bx, curr_operand.layout);
282 scratch.storage_live(bx);
283 curr_operand.store_with_annotation(bx, scratch);
284
285 // We retag the contents of the place
286 self.retag_variants(bx, scratch, discr_val, variant_plans);
287
288 // Afterward, we load the now-updated operand and end the lifetime of the place.
289 let updated_op = bx.load_operand(scratch);
290 scratch.storage_dead(bx);
291
292 match updated_op.val {
293 OperandValue::ZeroSized | OperandValue::Ref(_) => {}
294 OperandValue::Immediate(imm) => builder.update_imm(offset, imm),
295 OperandValue::Pair(fst, snd) => {
296 builder.update_imm(offset, fst);
297 builder.update_imm(offset + Size::from_bytes(1), snd)
298 }
299 }
300 }
301 }
302 }
303 }
304 }
305
306 fn retag_place(
307 &mut self,
308 bx: &mut Bx,
309 plan: &RetagPlan<Bx::Value>,
310 place: PlaceRef<'tcx, Bx::Value>,
311 ) {
312 match plan {
313 RetagPlan::EmitRetag(info) => {
314 bx.retag_mem(place.val.llval, info);
315 }
316 RetagPlan::Recurse { field_plans, variant_plans } => {
317 for (ix, plan) in field_plans {
318 let field_place = place.project_field(bx, ix.as_usize());
319 self.retag_place(bx, &plan, field_place);
320 }
321 if !variant_plans.is_empty() {
322 let operand = bx.load_operand(place);
323 let discr_ty = place.layout.ty.discriminant_ty(bx.tcx());
324 let discr_val = operand.codegen_get_discr(self, bx, discr_ty);
325 self.retag_variants(bx, place, discr_val, variant_plans);
326 }
327 }
328 }
329 }
330
331 /// Retags each variant of a [`PlaceRef`] with the given discriminant.
332 fn retag_variants(
333 &mut self,
334 bx: &mut Bx,
335 place: PlaceRef<'tcx, Bx::Value>,
336 discr: Bx::Value,
337 variant_plans: &FxIndexMap<VariantIdx, RetagPlan<Bx::Value>>,
338 ) {
339 let layout = place.layout;
340
341 let root_block = bx.llbb();
342 let mut variant_blocks = Vec::with_capacity(variant_plans.len());
343 let join_block = bx.append_sibling_block("retag_join");
344
345 for (ix, plan) in variant_plans {
346 let variant_discr = layout.ty.discriminant_for_variant(bx.tcx(), *ix);
347 let variant_discr_val = variant_discr.expect("Invalid variant index.").val;
348
349 let variant_block = bx.append_sibling_block("retag_variant");
350 bx.switch_to_block(variant_block);
351
352 let variant_place = place.project_downcast(bx, *ix);
353 self.retag_place(bx, plan, variant_place);
354
355 variant_blocks.push((variant_discr_val, variant_block));
356 bx.br(join_block);
357 }
358
359 bx.switch_to_block(root_block);
360 bx.switch(discr, join_block, variant_blocks.into_iter());
361 bx.switch_to_block(join_block);
198362 }
199363}
compiler/rustc_expand/src/base.rs+18-57
......@@ -503,39 +503,27 @@ pub trait MacResult {
503503 }
504504}
505505
506macro_rules! make_MacEager {
507 ( $( $fld:ident: $t:ty, )* ) => {
508 /// `MacResult` implementation for the common case where you've already
509 /// built each form of AST that you might return.
510 #[derive(Default)]
511 pub struct MacEager {
512 $(
513 pub $fld: Option<$t>,
514 )*
515 }
506/// `MacResult` implementation for the common case where you've already
507/// built each form of AST that you might return.
508#[derive(Default)]
509pub struct MacEager {
510 pub expr: Option<Box<ast::Expr>>,
511 pub items: Option<SmallVec<[Box<ast::Item>; 1]>>,
512 pub ty: Option<Box<ast::Ty>>,
513}
516514
517 impl MacEager {
518 $(
519 pub fn $fld(v: $t) -> Box<dyn MacResult> {
520 Box::new(MacEager {
521 $fld: Some(v),
522 ..Default::default()
523 })
524 }
525 )*
526 }
515impl MacEager {
516 pub fn expr(v: Box<ast::Expr>) -> Box<dyn MacResult> {
517 Box::new(MacEager { expr: Some(v), ..Default::default() })
518 }
519
520 pub fn items(v: SmallVec<[Box<ast::Item>; 1]>) -> Box<dyn MacResult> {
521 Box::new(MacEager { items: Some(v), ..Default::default() })
527522 }
528}
529523
530make_MacEager! {
531 expr: Box<ast::Expr>,
532 pat: Box<ast::Pat>,
533 items: SmallVec<[Box<ast::Item>; 1]>,
534 impl_items: SmallVec<[Box<ast::AssocItem>; 1]>,
535 trait_items: SmallVec<[Box<ast::AssocItem>; 1]>,
536 foreign_items: SmallVec<[Box<ast::ForeignItem>; 1]>,
537 stmts: SmallVec<[ast::Stmt; 1]>,
538 ty: Box<ast::Ty>,
524 pub fn ty(v: Box<ast::Ty>) -> Box<dyn MacResult> {
525 Box::new(MacEager { ty: Some(v), ..Default::default() })
526 }
539527}
540528
541529impl MacResult for MacEager {
......@@ -547,34 +535,7 @@ impl MacResult for MacEager {
547535 self.items
548536 }
549537
550 fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
551 self.impl_items
552 }
553
554 fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
555 self.impl_items
556 }
557
558 fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
559 self.trait_items
560 }
561
562 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
563 self.foreign_items
564 }
565
566 fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
567 if self.stmts.as_ref().is_none_or(|s| s.is_empty()) {
568 make_stmts_default(self.make_expr())
569 } else {
570 self.stmts
571 }
572 }
573
574538 fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
575 if let Some(p) = self.pat {
576 return Some(p);
577 }
578539 if let Some(e) = self.expr {
579540 if matches!(e.kind, ast::ExprKind::Lit(_) | ast::ExprKind::IncludedBytes(_)) {
580541 return Some(Box::new(ast::Pat {
compiler/rustc_hir_analysis/src/check/mod.rs+2-3
......@@ -479,10 +479,9 @@ fn fn_sig_suggestion<'tcx>(
479479 }
480480 }
481481 };
482 Some(format!("{splat}{arg_ty}"))
482 format!("{splat}{arg_ty}")
483483 })
484 .chain(std::iter::once(if sig.c_variadic() { Some("...".to_string()) } else { None }))
485 .flatten()
484 .chain(if sig.c_variadic() { Some("...".to_string()) } else { None })
486485 .collect::<Vec<String>>()
487486 .join(", ");
488487 let mut output = sig.output();
compiler/rustc_hir_analysis/src/check/wfcheck.rs+2-2
......@@ -1217,7 +1217,7 @@ fn check_eiis_fn(tcx: TyCtxt<'_>, def_id: LocalDefId) {
12171217 // does the function have an EiiImpl attribute? that contains the defid of a *macro*
12181218 // that was used to mark the implementation. This is a two step process.
12191219 for EiiImpl { resolution, span, .. } in
1220 find_attr!(tcx, def_id, EiiImpls(impls) => impls).into_iter().flatten()
1220 find_attr!(tcx, def_id, EiiImpls(impls) => impls).into_flat_iter()
12211221 {
12221222 let (foreign_item, name) = match resolution {
12231223 EiiImplResolution::Macro(def_id) => {
......@@ -1244,7 +1244,7 @@ fn check_eiis_static<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, ty: Ty<'tcx>)
12441244 // does the function have an EiiImpl attribute? that contains the defid of a *macro*
12451245 // that was used to mark the implementation. This is a two step process.
12461246 for EiiImpl { resolution, span, .. } in
1247 find_attr!(tcx, def_id, EiiImpls(impls) => impls).into_iter().flatten()
1247 find_attr!(tcx, def_id, EiiImpls(impls) => impls).into_flat_iter()
12481248 {
12491249 let (foreign_item, name) = match resolution {
12501250 EiiImplResolution::Macro(def_id) => {
compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs+9-7
......@@ -984,15 +984,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
984984 ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
985985 // `<Foo as Iterator>::Item = String`.
986986 let projection_term = pred.projection_term;
987 let quiet_projection_term = projection_term
988 .with_replaced_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
989
990987 let term = pred.term;
988 let self_ty = projection_term.args.get(0).and_then(|arg| arg.as_type())?;
989
991990 let obligation = format!("{projection_term} = {term}");
991 let quiet_projection_term = projection_term
992 .with_replaced_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
992993 let quiet = format!("{quiet_projection_term} = {term}");
993994
994 bound_span_label(projection_term.self_ty(), &obligation, &quiet);
995 Some((obligation, projection_term.self_ty()))
995 bound_span_label(self_ty, &obligation, &quiet);
996
997 Some(obligation)
996998 }
997999 ty::PredicateKind::Clause(ty::ClauseKind::Trait(poly_trait_ref)) => {
9981000 let p = poly_trait_ref.trait_ref;
......@@ -1001,7 +1003,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10011003 let obligation = format!("{self_ty}: {path}");
10021004 let quiet = format!("_: {path}");
10031005 bound_span_label(self_ty, &obligation, &quiet);
1004 Some((obligation, self_ty))
1006 Some(obligation)
10051007 }
10061008 _ => None,
10071009 }
......@@ -1013,7 +1015,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10131015 .into_iter()
10141016 .map(|error| error.root_obligation.predicate)
10151017 .filter_map(format_pred)
1016 .map(|(p, _)| format!("`{p}`"))
1018 .map(|p| format!("`{p}`"))
10171019 .collect();
10181020 bounds.sort();
10191021 bounds.dedup();
compiler/rustc_hir_analysis/src/lib.rs+1
......@@ -60,6 +60,7 @@ This API is completely unstable and subject to change.
6060#![feature(gen_blocks)]
6161#![feature(iter_intersperse)]
6262#![feature(never_type)]
63#![feature(option_into_flat_iter)]
6364#![feature(slice_partition_dedup)]
6465#![feature(try_blocks)]
6566#![feature(unwrap_infallible)]
compiler/rustc_hir_typeck/src/coercion.rs+1-14
......@@ -673,7 +673,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
673673 let mut coercion = self.unify_and(
674674 coerce_target,
675675 target,
676 reborrow.into_iter().flat_map(|(deref, autoref)| [deref, autoref]),
676 reborrow.map(|(deref, autoref)| [deref, autoref]).into_flat_iter(),
677677 Adjust::Pointer(PointerCoercion::Unsize),
678678 ForceLeakCheck::No,
679679 )?;
......@@ -737,19 +737,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
737737 {
738738 self.resolve_vars_if_possible(trait_pred)
739739 }
740 // Eagerly process alias-relate obligations in new trait solver,
741 // since these can be emitted in the process of solving trait goals,
742 // but we need to constrain vars before processing goals mentioning
743 // them.
744 Some(ty::PredicateKind::AliasRelate(..)) => {
745 let ocx = ObligationCtxt::new(self);
746 ocx.register_obligation(obligation);
747 if !ocx.try_evaluate_obligations().is_empty() {
748 return Err(TypeError::Mismatch);
749 }
750 coercion.obligations.extend(ocx.into_pending_obligations());
751 continue;
752 }
753740 _ => {
754741 coercion.obligations.push(obligation);
755742 continue;
compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs-1
......@@ -55,7 +55,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5555 | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
5656 | ty::PredicateKind::DynCompatible(..)
5757 | ty::PredicateKind::NormalizesTo(..)
58 | ty::PredicateKind::AliasRelate(..)
5958 | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
6059 | ty::PredicateKind::ConstEquate(..)
6160 | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
compiler/rustc_hir_typeck/src/lib.rs+1
......@@ -3,6 +3,7 @@
33#![feature(iter_intersperse)]
44#![feature(iter_order_by)]
55#![feature(never_type)]
6#![feature(option_into_flat_iter)]
67#![feature(option_reference_flattening)]
78#![feature(trim_prefix_suffix)]
89// tidy-alphabetical-end
compiler/rustc_hir_typeck/src/method/suggest.rs+1-1
......@@ -266,7 +266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
266266 // NOTE: Reporting a method error should also suppress any unused trait errors,
267267 // since the method error is very possibly the reason why the trait wasn't used.
268268 for &import_id in
269 self.tcx.in_scope_traits(call_id).into_iter().flatten().flat_map(|c| c.import_ids)
269 self.tcx.in_scope_traits(call_id).into_flat_iter().flat_map(|c| c.import_ids)
270270 {
271271 self.typeck_results.borrow_mut().used_trait_imports.insert(import_id);
272272 }
compiler/rustc_infer/src/infer/relate/generalize.rs+54-18
......@@ -6,8 +6,8 @@ use rustc_hir::def_id::DefId;
66use rustc_middle::bug;
77use rustc_middle::ty::error::TypeError;
88use rustc_middle::ty::{
9 self, AliasRelationDirection, InferConst, Term, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
10 TypeVisitableExt, TypeVisitor,
9 self, InferConst, Term, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
10 TypeVisitor,
1111};
1212use rustc_span::Span;
1313use tracing::{debug, instrument, warn};
......@@ -168,25 +168,61 @@ impl<'tcx> InferCtxt<'tcx> {
168168 // cyclic type. We instead delay the unification in case
169169 // the alias can be normalized to something which does not
170170 // mention `?0`.
171 let Some(source_alias) = source_term.to_alias_term() else {
172 bug!("generalized `{source_term:?} to infer, not an alias");
173 };
171174 if self.next_trait_solver() {
172 let (lhs, rhs, direction) = match instantiation_variance {
173 ty::Invariant => {
174 (generalized_term, source_term, AliasRelationDirection::Equate)
175 }
176 ty::Covariant => {
177 (generalized_term, source_term, AliasRelationDirection::Subtype)
178 }
179 ty::Contravariant => {
180 (source_term, generalized_term, AliasRelationDirection::Subtype)
175 if let Some(generalized_ty) = generalized_term.as_type() {
176 match instantiation_variance {
177 ty::Invariant => relation.register_predicates([ty::ProjectionPredicate {
178 projection_term: source_alias.into(),
179 term: generalized_ty.into(),
180 }]),
181 ty::Covariant => {
182 // Generate a new var, then do:
183 // `source_alias == ?A && ?A <: generalized_ty`
184 let new_var = self.next_ty_var(relation.span());
185 relation.register_predicates([
186 ty::PredicateKind::Subtype(ty::SubtypePredicate {
187 a_is_expected: !target_is_expected,
188 a: new_var,
189 b: generalized_ty,
190 }),
191 ty::PredicateKind::Clause(ty::ClauseKind::Projection(
192 ty::ProjectionPredicate {
193 projection_term: source_alias.into(),
194 term: new_var.into(),
195 },
196 )),
197 ]);
198 }
199 ty::Contravariant => {
200 // a :> b is b <: a
201 let new_var = self.next_ty_var(relation.span());
202 relation.register_predicates([
203 ty::PredicateKind::Subtype(ty::SubtypePredicate {
204 a_is_expected: target_is_expected,
205 a: generalized_ty,
206 b: new_var,
207 }),
208 ty::PredicateKind::Clause(ty::ClauseKind::Projection(
209 ty::ProjectionPredicate {
210 projection_term: source_alias.into(),
211 term: new_var.into(),
212 },
213 )),
214 ]);
215 }
216 ty::Bivariant => unreachable!("bivariant generalization"),
181217 }
182 ty::Bivariant => unreachable!("bivariant generalization"),
183 };
184
185 relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]);
218 } else {
219 debug_assert_eq!(instantiation_variance, ty::Variance::Invariant);
220 relation.register_predicates([ty::ProjectionPredicate {
221 projection_term: source_alias,
222 term: generalized_term,
223 }]);
224 }
186225 } else {
187 let Some(source_alias) = source_term.to_alias_term() else {
188 bug!("generalized `{source_term:?} to infer, not an alias");
189 };
190226 match source_alias.kind {
191227 ty::AliasTermKind::ProjectionTy { .. }
192228 | ty::AliasTermKind::ProjectionConst { .. } => {
compiler/rustc_infer/src/infer/relate/lattice.rs+3-7
......@@ -291,12 +291,8 @@ impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
291291 }))
292292 }
293293
294 fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
295 self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate(
296 a.into(),
297 b.into(),
298 // FIXME(deferred_projection_equality): This isn't right, I think?
299 ty::AliasRelationDirection::Equate,
300 ))]);
294 fn ambient_variance(&self) -> ty::Variance {
295 // FIXME(deferred_projection_equality): This isn't right, I think?
296 ty::Variance::Invariant
301297 }
302298}
compiler/rustc_infer/src/infer/relate/type_relating.rs+2-22
......@@ -384,27 +384,7 @@ impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for TypeRelating<'_, 'tcx>
384384 }))
385385 }
386386
387 fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
388 self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
389 ty::Covariant => ty::PredicateKind::AliasRelate(
390 a.into(),
391 b.into(),
392 ty::AliasRelationDirection::Subtype,
393 ),
394 // a :> b is b <: a
395 ty::Contravariant => ty::PredicateKind::AliasRelate(
396 b.into(),
397 a.into(),
398 ty::AliasRelationDirection::Subtype,
399 ),
400 ty::Invariant => ty::PredicateKind::AliasRelate(
401 a.into(),
402 b.into(),
403 ty::AliasRelationDirection::Equate,
404 ),
405 ty::Bivariant => {
406 unreachable!("Expected bivariance to be handled in relate_with_variance")
407 }
408 })]);
387 fn ambient_variance(&self) -> ty::Variance {
388 self.ambient_variance
409389 }
410390}
compiler/rustc_lint/src/if_let_rescope.rs+1-2
......@@ -349,8 +349,7 @@ impl Subdiagnostic for IfLetRescopeRewrite {
349349 closing_brackets
350350 .empty_alt
351351 .then_some(" _ => {}".chars())
352 .into_iter()
353 .flatten()
352 .into_flat_iter()
354353 .chain(repeat_n('}', closing_brackets.count))
355354 .collect(),
356355 ));
compiler/rustc_lint/src/lib.rs+1
......@@ -23,6 +23,7 @@
2323#![allow(internal_features)]
2424#![feature(deref_patterns)]
2525#![feature(iter_order_by)]
26#![feature(option_into_flat_iter)]
2627#![feature(rustc_attrs)]
2728#![feature(titlecase)]
2829#![feature(try_blocks)]
compiler/rustc_lint/src/types.rs+7-3
......@@ -793,7 +793,7 @@ fn get_nullable_type<'tcx>(
793793 return get_nullable_type(tcx, typing_env, inner_field_ty);
794794 }
795795 ty::Pat(base, ..) => return get_nullable_type(tcx, typing_env, base),
796 ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => ty,
796 ty::Int(_) | ty::Uint(_) | ty::Char | ty::RawPtr(..) => ty,
797797 // As these types are always non-null, the nullable equivalent of
798798 // `Option<T>` of these types are their raw pointer counterparts.
799799 ty::Ref(_region, ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
......@@ -895,10 +895,14 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
895895 WrappingRange { start: 0, end }
896896 if end == field_ty_scalar.size(&tcx).unsigned_int_max() - 1 =>
897897 {
898 return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
898 return Some(get_nullable_type(tcx, typing_env, field_ty).expect(
899 "known non-null scalar type should have a nullable representation",
900 ));
899901 }
900902 WrappingRange { start: 1, .. } => {
901 return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
903 return Some(get_nullable_type(tcx, typing_env, field_ty).expect(
904 "known non-null scalar type should have a nullable representation",
905 ));
902906 }
903907 WrappingRange { start, end } => {
904908 unreachable!("Unhandled start and end range: ({}, {})", start, end)
compiler/rustc_metadata/src/eii.rs+1-1
......@@ -25,7 +25,7 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap
2525
2626 // iterate over all items in the current crate
2727 for id in tcx.hir_crate_items(()).eiis() {
28 for i in find_attr!(tcx, id, EiiImpls(e) => e).into_iter().flatten() {
28 for i in find_attr!(tcx, id, EiiImpls(e) => e).into_flat_iter() {
2929 let decl = match i.resolution {
3030 EiiImplResolution::Macro(macro_defid) => {
3131 // find the decl for this one if it wasn't in yet (maybe it's from the local crate? not very useful but not illegal)
compiler/rustc_metadata/src/lib.rs+1
......@@ -8,6 +8,7 @@
88#![feature(macro_metavar_expr)]
99#![feature(min_specialization)]
1010#![feature(never_type)]
11#![feature(option_into_flat_iter)]
1112#![feature(proc_macro_internals)]
1213#![feature(trusted_len)]
1314// tidy-alphabetical-end
compiler/rustc_metadata/src/locator.rs+2-3
......@@ -325,9 +325,8 @@ impl<'a> CrateLocator<'a> {
325325 sess.opts
326326 .externs
327327 .get(crate_name.as_str())
328 .into_iter()
329 .filter_map(|entry| entry.files())
330 .flatten()
328 .and_then(|entry| entry.files())
329 .into_flat_iter()
331330 .cloned()
332331 .collect()
333332 } else {
compiler/rustc_metadata/src/native_libs.rs+1-3
......@@ -248,9 +248,7 @@ impl<'tcx> Collector<'tcx> {
248248 return;
249249 }
250250
251 for attr in
252 find_attr!(self.tcx, def_id, Link(links, _) => links).iter().map(|v| v.iter()).flatten()
253 {
251 for attr in find_attr!(self.tcx, def_id, Link(links, _) => links).into_flat_iter() {
254252 let dll_imports = match attr.kind {
255253 NativeLibKind::RawDylib { .. } => foreign_items
256254 .iter()
compiler/rustc_metadata/src/rmeta/decoder.rs+6-4
......@@ -2038,10 +2038,12 @@ impl CrateMetadata {
20382038 krate: CrateNum,
20392039 ) -> impl Iterator<Item = DefId> {
20402040 gen move {
2041 for def_id in self.root.proc_macro_data.as_ref().into_iter().flat_map(move |data| {
2042 data.macros.decode((self, tcx)).map(move |(index, _)| DefId { index, krate })
2043 }) {
2044 yield def_id;
2041 if let Some(data) = &self.root.proc_macro_data {
2042 for def_id in
2043 data.macros.decode((self, tcx)).map(move |(index, _)| DefId { index, krate })
2044 {
2045 yield def_id;
2046 }
20452047 }
20462048 }
20472049 }
compiler/rustc_middle/src/lib.rs+1
......@@ -46,6 +46,7 @@
4646#![feature(min_specialization)]
4747#![feature(negative_impls)]
4848#![feature(never_type)]
49#![feature(option_into_flat_iter)]
4950#![feature(ptr_alignment_type)]
5051#![feature(range_bounds_is_empty)]
5152#![feature(rustc_attrs)]
compiler/rustc_middle/src/mir/consts.rs+1-1
......@@ -18,7 +18,7 @@ use crate::ty::{self, ConstKind, GenericArgsRef, ScalarInt, Ty, TyCtxt};
1818/// Represents the result of const evaluation via the `eval_to_allocation` query.
1919/// Not to be confused with `ConstAllocation`, which directly refers to the underlying data!
2020/// Here we indirect via an `AllocId`.
21#[derive(Copy, Clone, StableHash, TyEncodable, TyDecodable, Debug, Hash, Eq, PartialEq)]
21#[derive(Copy, Clone, StableHash, TyEncodable, TyDecodable, Debug, Eq, PartialEq)]
2222pub struct ConstAlloc<'tcx> {
2323 /// The value lives here, at offset 0, and that allocation definitely is an `AllocKind::Memory`
2424 /// (so you can use `AllocMap::unwrap_memory`).
compiler/rustc_middle/src/mir/coverage.rs+1-1
......@@ -70,7 +70,7 @@ impl Debug for CovTerm {
7070 }
7171}
7272
73#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, StableHash)]
73#[derive(Clone, PartialEq, TyEncodable, TyDecodable, StableHash)]
7474pub enum CoverageKind {
7575 /// Marks a span that might otherwise not be represented in MIR, so that
7676 /// coverage instrumentation can associate it with its enclosing block/BCB.
compiler/rustc_middle/src/mir/mod.rs+1-1
......@@ -1558,7 +1558,7 @@ impl UserTypeProjections {
15581558/// * `let (x, _): T = ...` -- here, the `projs` vector would contain
15591559/// `field[0]` (aka `.0`), indicating that the type of `s` is
15601560/// determined by finding the type of the `.0` field from `T`.
1561#[derive(Clone, Debug, TyEncodable, TyDecodable, Hash, StableHash, PartialEq)]
1561#[derive(Clone, Debug, TyEncodable, TyDecodable, StableHash, PartialEq)]
15621562#[derive(TypeFoldable, TypeVisitable)]
15631563pub struct UserTypeProjection {
15641564 pub base: UserTypeAnnotationIndex,
compiler/rustc_middle/src/mir/syntax.rs+21-39
......@@ -300,7 +300,7 @@ pub enum FakeBorrowKind {
300300/// Not all of these are allowed at every [`MirPhase`]. Check the documentation there to see which
301301/// ones you do not have to worry about. The MIR validator will generally enforce such restrictions,
302302/// causing an ICE if they are violated.
303#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, StableHash)]
303#[derive(Clone, PartialEq, TyEncodable, TyDecodable, StableHash)]
304304#[derive(TypeFoldable, TypeVisitable)]
305305pub enum StatementKind<'tcx> {
306306 /// Assign statements roughly correspond to an assignment in Rust proper (`x = ...`) except
......@@ -455,17 +455,8 @@ pub enum StatementKind<'tcx> {
455455 },
456456}
457457
458#[derive(
459 Clone,
460 TyEncodable,
461 TyDecodable,
462 Debug,
463 PartialEq,
464 Hash,
465 StableHash,
466 TypeFoldable,
467 TypeVisitable
468)]
458#[derive(Clone, TyEncodable, TyDecodable, Debug, PartialEq, StableHash)]
459#[derive(TypeFoldable, TypeVisitable)]
469460pub enum NonDivergingIntrinsic<'tcx> {
470461 /// Denotes a call to the intrinsic function `assume`.
471462 ///
......@@ -492,7 +483,7 @@ pub enum NonDivergingIntrinsic<'tcx> {
492483}
493484
494485/// Describes whether this operand use performs a retag.
495#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, Hash, StableHash)]
486#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, StableHash)]
496487#[rustc_pass_by_value]
497488pub enum WithRetag {
498489 Yes,
......@@ -511,7 +502,7 @@ impl WithRetag {
511502}
512503
513504/// The `FakeReadCause` describes the type of pattern why a FakeRead statement exists.
514#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, Hash, StableHash, PartialEq)]
505#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, StableHash, PartialEq)]
515506pub enum FakeReadCause {
516507 /// A fake read injected into a match guard to ensure that the discriminants
517508 /// that are being matched on aren't modified while the match guard is being
......@@ -617,7 +608,7 @@ pub enum FakeReadCause {
617608 ForIndex,
618609}
619610
620#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, StableHash)]
611#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, StableHash)]
621612#[derive(TypeFoldable, TypeVisitable)]
622613pub struct CopyNonOverlapping<'tcx> {
623614 pub src: Operand<'tcx>,
......@@ -628,7 +619,7 @@ pub struct CopyNonOverlapping<'tcx> {
628619
629620/// Represents how a [`TerminatorKind::Call`] was constructed.
630621/// Used only for diagnostics.
631#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, StableHash)]
622#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, StableHash)]
632623#[derive(TypeFoldable, TypeVisitable)]
633624pub enum CallSource {
634625 /// This came from something such as `a > b` or `a + b`. In THIR, if `from_hir_call`
......@@ -648,7 +639,7 @@ pub enum CallSource {
648639 Normal,
649640}
650641
651#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, Hash, StableHash, PartialEq)]
642#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, StableHash, PartialEq)]
652643#[derive(TypeFoldable, TypeVisitable)]
653644/// The macro that an inline assembly block was created by
654645pub enum InlineAsmMacro {
......@@ -688,7 +679,7 @@ pub enum InlineAsmMacro {
688679/// deleting self edges and duplicate edges in the process. Now remove all vertices from `G`
689680/// that are not cleanup vertices or are not reachable. The resulting graph must be an inverted
690681/// tree, that is each vertex may have at most one successor and there may be no cycles.
691#[derive(Clone, TyEncodable, TyDecodable, Hash, StableHash, PartialEq, TypeFoldable, TypeVisitable)]
682#[derive(Clone, TyEncodable, TyDecodable, StableHash, PartialEq, TypeFoldable, TypeVisitable)]
692683pub enum TerminatorKind<'tcx> {
693684 /// Block has one successor; we continue execution there.
694685 Goto { target: BasicBlock },
......@@ -973,22 +964,13 @@ pub enum TerminatorKind<'tcx> {
973964 },
974965}
975966
976#[derive(
977 Clone,
978 Debug,
979 TyEncodable,
980 TyDecodable,
981 Hash,
982 StableHash,
983 PartialEq,
984 TypeFoldable,
985 TypeVisitable
986)]
967#[derive(Clone, Debug, TyEncodable, TyDecodable, StableHash, PartialEq)]
968#[derive(TypeFoldable, TypeVisitable)]
987969pub enum BackwardIncompatibleDropReason {
988970 Edition2024,
989971}
990972
991#[derive(Debug, Clone, TyEncodable, TyDecodable, Hash, StableHash, PartialEq)]
973#[derive(Debug, Clone, TyEncodable, TyDecodable, StableHash, PartialEq)]
992974pub struct SwitchTargets {
993975 /// Possible values. For each value, the location to branch to is found in
994976 /// the corresponding element in the `targets` vector.
......@@ -1018,7 +1000,7 @@ pub struct SwitchTargets {
10181000}
10191001
10201002/// Action to be taken when a stack unwind happens.
1021#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, StableHash)]
1003#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, StableHash)]
10221004#[derive(TypeFoldable, TypeVisitable)]
10231005pub enum UnwindAction {
10241006 /// No action is to be taken. Continue unwinding.
......@@ -1037,7 +1019,7 @@ pub enum UnwindAction {
10371019}
10381020
10391021/// The reason we are terminating the process during unwinding.
1040#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, StableHash)]
1022#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, StableHash)]
10411023#[derive(TypeFoldable, TypeVisitable)]
10421024pub enum UnwindTerminateReason {
10431025 /// Unwinding is just not possible given the ABI of this function.
......@@ -1048,7 +1030,7 @@ pub enum UnwindTerminateReason {
10481030}
10491031
10501032/// Information about an assertion failure.
1051#[derive(Clone, Hash, StableHash, PartialEq, Debug)]
1033#[derive(Clone, StableHash, PartialEq, Debug)]
10521034#[derive(TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
10531035pub enum AssertKind<O> {
10541036 BoundsCheck { len: O, index: O },
......@@ -1064,7 +1046,7 @@ pub enum AssertKind<O> {
10641046 InvalidEnumConstruction(O),
10651047}
10661048
1067#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, StableHash)]
1049#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, StableHash)]
10681050#[derive(TypeFoldable, TypeVisitable)]
10691051pub enum InlineAsmOperand<'tcx> {
10701052 In {
......@@ -1292,7 +1274,7 @@ pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
12921274/// **Needs clarification:** Is loading a place that has its variant index set well-formed? Miri
12931275/// currently implements it, but it seems like this may be something to check against in the
12941276/// validator.
1295#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, StableHash, TypeFoldable, TypeVisitable)]
1277#[derive(Clone, PartialEq, TyEncodable, TyDecodable, StableHash, TypeFoldable, TypeVisitable)]
12961278pub enum Operand<'tcx> {
12971279 /// Creates a value by loading the given place.
12981280 ///
......@@ -1327,7 +1309,7 @@ pub enum Operand<'tcx> {
13271309 RuntimeChecks(RuntimeChecks),
13281310}
13291311
1330#[derive(Clone, Copy, PartialEq, TyEncodable, TyDecodable, Hash, StableHash)]
1312#[derive(Clone, Copy, PartialEq, TyEncodable, TyDecodable, StableHash)]
13311313#[derive(TypeFoldable, TypeVisitable)]
13321314pub struct ConstOperand<'tcx> {
13331315 pub span: Span,
......@@ -1352,7 +1334,7 @@ pub struct ConstOperand<'tcx> {
13521334/// Computing any rvalue begins by evaluating the places and operands in some order (**Needs
13531335/// clarification**: Which order?). These are then used to produce a "value" - the same kind of
13541336/// value that an [`Operand`] produces.
1355#[derive(Clone, TyEncodable, TyDecodable, Hash, StableHash, PartialEq, TypeFoldable, TypeVisitable)]
1337#[derive(Clone, TyEncodable, TyDecodable, StableHash, PartialEq, TypeFoldable, TypeVisitable)]
13561338pub enum Rvalue<'tcx> {
13571339 /// Yields the operand unchanged, except for a potential retag.
13581340 Use(Operand<'tcx>, WithRetag),
......@@ -1534,7 +1516,7 @@ pub enum CoercionSource {
15341516 Implicit,
15351517}
15361518
1537#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, StableHash)]
1519#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, StableHash)]
15381520#[derive(TypeFoldable, TypeVisitable)]
15391521pub enum AggregateKind<'tcx> {
15401522 /// The type is of the element
......@@ -1703,7 +1685,7 @@ pub enum BinOp {
17031685
17041686// Assignment operators, e.g. `+=`. See comments on the corresponding variants
17051687// in `BinOp` for details.
1706#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, StableHash)]
1688#[derive(Copy, Clone, Debug, PartialEq, Eq, StableHash)]
17071689pub enum AssignOp {
17081690 AddAssign,
17091691 SubAssign,
compiler/rustc_middle/src/ty/print/pretty.rs-5
......@@ -3269,11 +3269,6 @@ define_print! {
32693269 }
32703270 ty::PredicateKind::Ambiguous => write!(p, "ambiguous")?,
32713271 ty::PredicateKind::NormalizesTo(data) => data.print(p)?,
3272 ty::PredicateKind::AliasRelate(t1, t2, dir) => {
3273 t1.print(p)?;
3274 write!(p, " {dir} ")?;
3275 t2.print(p)?;
3276 }
32773272 }
32783273 }
32793274
compiler/rustc_middle/src/ty/sty.rs+15-18
......@@ -769,25 +769,22 @@ impl<'tcx> Ty<'tcx> {
769769 .projection_bounds()
770770 .filter(|item| !tcx.generics_require_sized_self(item.item_def_id()))
771771 .count();
772 let expected_count: usize = obj
773 .principal_def_id()
774 .into_iter()
775 .flat_map(|principal_def_id| {
776 // IMPORTANT: This has to agree with HIR ty lowering of dyn trait!
777 elaborate::supertraits(
778 tcx,
779 ty::Binder::dummy(ty::TraitRef::identity(tcx, principal_def_id)),
780 )
781 .map(|principal| {
782 tcx.associated_items(principal.def_id())
783 .in_definition_order()
784 .filter(|item| item.is_type() || item.is_type_const())
785 .filter(|item| !item.is_impl_trait_in_trait())
786 .filter(|item| !tcx.generics_require_sized_self(item.def_id))
787 .count()
788 })
772 let expected_count: usize = obj.principal_def_id().map_or(0, |principal_def_id| {
773 // IMPORTANT: This has to agree with HIR ty lowering of dyn trait!
774 elaborate::supertraits(
775 tcx,
776 ty::Binder::dummy(ty::TraitRef::identity(tcx, principal_def_id)),
777 )
778 .map(|principal| {
779 tcx.associated_items(principal.def_id())
780 .in_definition_order()
781 .filter(|item| item.is_type() || item.is_type_const())
782 .filter(|item| !item.is_impl_trait_in_trait())
783 .filter(|item| !tcx.generics_require_sized_self(item.def_id))
784 .count()
789785 })
790 .sum();
786 .sum()
787 });
791788 assert_eq!(
792789 projection_count, expected_count,
793790 "expected {obj:?} to have {expected_count} projections, \
compiler/rustc_middle/src/ty/typeck_results.rs+2-2
......@@ -537,8 +537,8 @@ impl<'tcx> TypeckResults<'tcx> {
537537 ) -> impl Iterator<Item = &ty::CapturedPlace<'tcx>> {
538538 self.closure_min_captures
539539 .get(&closure_def_id)
540 .map(|closure_min_captures| closure_min_captures.values().flat_map(|v| v.iter()))
541 .into_iter()
540 .map(|closure_min_captures| closure_min_captures.values())
541 .into_flat_iter()
542542 .flatten()
543543 }
544544
compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs+1-1
......@@ -126,6 +126,6 @@ where
126126 sink_edge = self.sink_edge_nodes.contains(node).then_some(self.sink);
127127 }
128128
129 real_edges.into_iter().flatten().chain(sink_edge)
129 real_edges.into_flat_iter().chain(sink_edge)
130130 }
131131}
compiler/rustc_mir_transform/src/lib.rs+1
......@@ -4,6 +4,7 @@
44#![feature(deref_patterns)]
55#![feature(impl_trait_in_assoc_type)]
66#![feature(iterator_try_collect)]
7#![feature(option_into_flat_iter)]
78#![feature(try_blocks)]
89#![feature(yeet_expr)]
910// tidy-alphabetical-end
compiler/rustc_next_trait_solver/src/canonical/mod.rs+9-2
......@@ -100,7 +100,6 @@ pub(super) fn instantiate_and_apply_query_response<D, I>(
100100 param_env: I::ParamEnv,
101101 original_values: &[I::GenericArg],
102102 response: CanonicalResponse<I>,
103 visible_for_leak_check: VisibleForLeakCheck,
104103 span: I::Span,
105104) -> (NestedNormalizationGoals<I>, Certainty)
106105where
......@@ -121,7 +120,15 @@ where
121120 match region_constraints {
122121 ExternalRegionConstraints::Old(r) => register_region_constraints(
123122 delegate,
124 r.iter().map(|(c, vis)| (*c, vis.and(visible_for_leak_check))),
123 r.iter().map(|(c, vis)| {
124 // FIXME: We should revisit and consider removing this after *assumptions on
125 // binders* is available, like once we had done in the stabilization of
126 // `-Znext-solver=coherence`(#121848).
127 // We ignore constraints from the nested goals in leak check. This is to match with
128 // the old solver's behavior, which has separated evaluation and fulfillment, and
129 // the former doesn't consider outlives obligations from the later.
130 (*c, vis.and(VisibleForLeakCheck::No))
131 }),
125132 span,
126133 ),
127134 ExternalRegionConstraints::NextGen(r) => {
compiler/rustc_next_trait_solver/src/solve/alias_relate.rs deleted-93
......@@ -1,93 +0,0 @@
1//! Implements the `AliasRelate` goal, which is used when unifying aliases.
2//! Doing this via a separate goal is called "deferred alias relation" and part
3//! of our more general approach to "lazy normalization".
4//!
5//! This is done by first structurally normalizing both sides of the goal, ending
6//! up in either a concrete type, rigid alias, or an infer variable.
7//! These are related further according to the rules below:
8//!
9//! (1.) If we end up with two rigid aliases, then we relate them structurally.
10//!
11//! (2.) If we end up with an infer var and a rigid alias, then we instantiate
12//! the infer var with the constructor of the alias and then recursively relate
13//! the terms.
14//!
15//! (3.) Otherwise, if we end with two rigid (non-projection) or infer types,
16//! relate them structurally.
17
18use rustc_type_ir::inherent::*;
19use rustc_type_ir::solve::{GoalSource, QueryResultOrRerunNonErased};
20use rustc_type_ir::{self as ty, Interner};
21use tracing::{instrument, trace};
22
23use crate::delegate::SolverDelegate;
24use crate::solve::{Certainty, EvalCtxt, Goal};
25
26impl<D, I> EvalCtxt<'_, D>
27where
28 D: SolverDelegate<Interner = I>,
29 I: Interner,
30{
31 #[instrument(level = "trace", skip(self), ret)]
32 pub(super) fn compute_alias_relate_goal(
33 &mut self,
34 goal: Goal<I, (I::Term, I::Term, ty::AliasRelationDirection)>,
35 ) -> QueryResultOrRerunNonErased<I> {
36 let cx = self.cx();
37 let Goal { param_env, predicate: (lhs, rhs, direction) } = goal;
38
39 // Check that the alias-relate goal is reasonable. Writeback for
40 // `coroutine_stalled_predicates` can replace alias terms with
41 // `{type error}` if the alias still contains infer vars, so we also
42 // accept alias-relate goals where one of the terms is an error.
43 debug_assert!(
44 lhs.to_alias_term().is_some()
45 || rhs.to_alias_term().is_some()
46 || lhs.is_error()
47 || rhs.is_error()
48 );
49
50 // Structurally normalize the lhs.
51 let lhs = if let Some(alias) = lhs.to_alias_term() {
52 let term = self.next_term_infer_of_alias_kind(alias);
53 self.add_goal(
54 GoalSource::TypeRelating,
55 goal.with(cx, ty::ProjectionPredicate { projection_term: alias, term }),
56 )?;
57 term
58 } else {
59 lhs
60 };
61
62 // Structurally normalize the rhs.
63 let rhs = if let Some(alias) = rhs.to_alias_term() {
64 let term = self.next_term_infer_of_alias_kind(alias);
65 self.add_goal(
66 GoalSource::TypeRelating,
67 goal.with(cx, ty::ProjectionPredicate { projection_term: alias, term }),
68 )?;
69 term
70 } else {
71 rhs
72 };
73
74 // Add a `make_canonical_response` probe step so that we treat this as
75 // a candidate, even if `try_evaluate_added_goals` bails due to an error.
76 // It's `Certainty::AMBIGUOUS` because this candidate is not "finished",
77 // since equating the normalized terms will lead to additional constraints.
78 self.inspect.make_canonical_response(Certainty::AMBIGUOUS);
79
80 // Apply the constraints.
81 self.try_evaluate_added_goals()?;
82 let lhs = self.resolve_vars_if_possible(lhs);
83 let rhs = self.resolve_vars_if_possible(rhs);
84 trace!(?lhs, ?rhs);
85
86 let variance = match direction {
87 ty::AliasRelationDirection::Equate => ty::Invariant,
88 ty::AliasRelationDirection::Subtype => ty::Covariant,
89 };
90 self.relate(param_env, lhs, variance, rhs)?;
91 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
92 }
93}
compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs+2-25
......@@ -733,29 +733,11 @@ where
733733 let has_changed =
734734 if !has_only_region_constraints(response) { HasChanged::Yes } else { HasChanged::No };
735735
736 // FIXME: We should revisit and consider removing this after
737 // *assumptions on binders* is available, like once we had done in the
738 // stabilization of `-Znext-solver=coherence`(#121848).
739 // We ignore constraints from the nested goals in leak check. This is to match
740 // with the old solver's behavior, which has separated evaluation and fulfillment,
741 // and the former doesn't consider outlives obligations from the later.
742 let vis = match goal.predicate.kind().skip_binder() {
743 ty::PredicateKind::Clause(_)
744 | ty::PredicateKind::DynCompatible(_)
745 | ty::PredicateKind::Subtype(_)
746 | ty::PredicateKind::Coerce(_)
747 | ty::PredicateKind::ConstEquate(_, _)
748 | ty::PredicateKind::Ambiguous
749 | ty::PredicateKind::NormalizesTo(_) => VisibleForLeakCheck::No,
750 ty::PredicateKind::AliasRelate(_, _, _) => VisibleForLeakCheck::Yes,
751 };
752
753736 let (normalization_nested_goals, certainty) = instantiate_and_apply_query_response(
754737 self.delegate,
755738 goal.param_env,
756739 &orig_values,
757740 response,
758 vis,
759741 self.origin_span,
760742 );
761743
......@@ -965,11 +947,6 @@ where
965947 ty::PredicateKind::NormalizesTo(predicate) => {
966948 ecx.compute_normalizes_to_goal(Goal { param_env, predicate })?
967949 }
968 ty::PredicateKind::AliasRelate(lhs, rhs, direction) => ecx
969 .compute_alias_relate_goal(Goal {
970 param_env,
971 predicate: (lhs, rhs, direction),
972 })?,
973950 ty::PredicateKind::Ambiguous => {
974951 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)?
975952 }
......@@ -1276,7 +1253,8 @@ where
12761253 let goals = self.delegate.relate(param_env, lhs, variance, rhs, self.origin_span)?;
12771254 for &goal in goals.iter() {
12781255 let source = match goal.predicate.kind().skip_binder() {
1279 ty::PredicateKind::Subtype { .. } | ty::PredicateKind::AliasRelate(..) => {
1256 ty::PredicateKind::Subtype { .. }
1257 | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) => {
12801258 GoalSource::TypeRelating
12811259 }
12821260 // FIXME(-Znext-solver=coinductive): should these WF goals also be unproductive?
......@@ -1814,7 +1792,6 @@ pub(super) fn evaluate_root_goal_for_proof_tree<D: SolverDelegate<Interner = I>,
18141792 goal.param_env,
18151793 &proof_tree.orig_values,
18161794 response,
1817 VisibleForLeakCheck::Yes,
18181795 origin_span,
18191796 );
18201797
compiler/rustc_next_trait_solver/src/solve/mod.rs-1
......@@ -11,7 +11,6 @@
1111//! For a high-level overview of how this solver works, check out the relevant
1212//! section of the rustc-dev-guide.
1313
14mod alias_relate;
1514mod assembly;
1615mod effect_goals;
1716mod eval_ctxt;
compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs+17-30
......@@ -82,7 +82,7 @@ where
8282 },
8383 |ecx| {
8484 ecx.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| {
85 this.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
85 this.instantiate_normalizes_to_as_rigid(goal)?;
8686 this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
8787 })
8888 },
......@@ -111,13 +111,9 @@ where
111111 Ok(())
112112 }
113113
114 /// When normalizing an associated item, constrain the expected term to `term`.
114 /// When normalizing an associated item, constrain the expected term to `value`.
115115 ///
116 /// We know `term` to always be a fully unconstrained inference variable, so
117 /// `eq` should never fail here. However, in case `term` contains aliases, we
118 /// emit nested `AliasRelate` goals to structurally normalize the alias.
119 ///
120 /// Additionally, when `term` is a const, this registers a `ConstArgHasType`
116 /// Additionally, when `value` is a const, this registers a `ConstArgHasType`
121117 /// goal to ensure that the const value's type matches the declared type of
122118 /// the alias it was normalized from.
123119 ///
......@@ -140,28 +136,25 @@ where
140136 fn instantiate_normalizes_to_term(
141137 &mut self,
142138 goal: Goal<I, NormalizesTo<I>>,
143 term: I::Term,
139 value: I::Term,
144140 ) -> Result<(), NoSolutionOrRerunNonErased> {
145 self.push_const_arg_has_type_goal(goal.param_env, goal.predicate.alias, term)?;
146 self.eq(goal.param_env, goal.predicate.term, term)
147 .expect("expected goal term to be fully unconstrained");
141 self.push_const_arg_has_type_goal(goal.param_env, goal.predicate.alias, value)?;
142 // While `goal.predicate.term` should always be a fully unconstrained inference variable,
143 // `eq` can still fail if `value` is not fully normalized, due to `eq` eagerly normalizing,
144 // and that normalization can fail.
145 self.eq(goal.param_env, goal.predicate.term, value)?;
148146 Ok(())
149147 }
150148
151 /// Unlike `instantiate_normalizes_to_term` this instantiates the expected term
152 /// with a rigid alias. Using this is pretty much always wrong.
153 fn structurally_instantiate_normalizes_to_term(
149 fn instantiate_normalizes_to_as_rigid(
154150 &mut self,
155151 goal: Goal<I, NormalizesTo<I>>,
156 term: ty::AliasTerm<I>,
157 ) {
158 self.relate(
152 ) -> Result<(), NoSolutionOrRerunNonErased> {
153 self.eq(
159154 goal.param_env,
160 term.to_term(self.cx(), ty::IsRigid::Yes),
161 ty::Invariant,
162155 goal.predicate.term,
156 goal.predicate.alias.to_term(self.cx(), ty::IsRigid::Yes),
163157 )
164 .expect("expected goal term to be fully unconstrained");
165158 }
166159}
167160
......@@ -356,10 +349,7 @@ where
356349 | ty::TypingMode::PostBorrowck { .. }
357350 | ty::TypingMode::PostAnalysis
358351 | ty::TypingMode::Codegen => {
359 ecx.structurally_instantiate_normalizes_to_term(
360 goal,
361 goal.predicate.alias,
362 );
352 ecx.instantiate_normalizes_to_as_rigid(goal)?;
363353 return ecx.evaluate_added_goals_and_make_canonical_response(
364354 Certainty::Yes,
365355 );
......@@ -394,7 +384,7 @@ where
394384 ecx.add_goal(GoalSource::Misc, goal.with(cx, PredicateKind::Ambiguous))?;
395385 return then(ecx, Certainty::Yes);
396386 } else {
397 ecx.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
387 ecx.instantiate_normalizes_to_as_rigid(goal)?;
398388 return then(ecx, Certainty::Yes);
399389 }
400390 } else {
......@@ -767,10 +757,7 @@ where
767757 // as rigid.
768758 return alias_bound_result.or_else(|NoSolution| {
769759 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|this| {
770 this.structurally_instantiate_normalizes_to_term(
771 goal,
772 goal.predicate.alias,
773 );
760 this.instantiate_normalizes_to_as_rigid(goal)?;
774761 this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
775762 })
776763 });
......@@ -1026,7 +1013,7 @@ where
10261013 // this impl candidate anyways. It's still a bit scuffed.
10271014 ty::Alias(ty::IsRigid::Yes, _) | ty::Param(_) | ty::Placeholder(..) => {
10281015 return ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
1029 ecx.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
1016 ecx.instantiate_normalizes_to_as_rigid(goal)?;
10301017 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
10311018 });
10321019 }
compiler/rustc_passes/src/lib.rs+4
......@@ -4,6 +4,10 @@
44//!
55//! This API is completely unstable and subject to change.
66
7// tidy-alphabetical-start
8#![feature(option_into_flat_iter)]
9// tidy-alphabetical-end
10
711use rustc_middle::query::Providers;
812
913pub mod abi_test;
compiler/rustc_passes/src/stability.rs+1-2
......@@ -1112,8 +1112,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
11121112 .iter()
11131113 .flat_map(|&cnum| {
11141114 find_attr!(tcx, cnum.as_def_id(), UnstableRemoved(rem_features) => rem_features)
1115 .into_iter()
1116 .flatten()
1115 .into_flat_iter()
11171116 })
11181117 .collect::<Vec<_>>();
11191118
compiler/rustc_public/src/ty.rs-7
......@@ -1526,7 +1526,6 @@ pub enum PredicateKind {
15261526 Coerce(CoercePredicate),
15271527 ConstEquate(TyConst, TyConst),
15281528 Ambiguous,
1529 AliasRelate(TermKind, TermKind, AliasRelationDirection),
15301529}
15311530
15321531#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
......@@ -1559,12 +1558,6 @@ pub struct CoercePredicate {
15591558 pub b: Ty,
15601559}
15611560
1562#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1563pub enum AliasRelationDirection {
1564 Equate,
1565 Subtype,
1566}
1567
15681561#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
15691562pub struct TraitPredicate {
15701563 pub trait_ref: TraitRef,
compiler/rustc_public/src/unstable/convert/stable/ty.rs-19
......@@ -749,13 +749,6 @@ impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> {
749749 }
750750 PredicateKind::Ambiguous => crate::ty::PredicateKind::Ambiguous,
751751 PredicateKind::NormalizesTo(_pred) => unimplemented!(),
752 PredicateKind::AliasRelate(a, b, alias_relation_direction) => {
753 crate::ty::PredicateKind::AliasRelate(
754 a.kind().stable(tables, cx),
755 b.kind().stable(tables, cx),
756 alias_relation_direction.stable(tables, cx),
757 )
758 }
759752 }
760753 }
761754}
......@@ -845,18 +838,6 @@ impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
845838 }
846839}
847840
848impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection {
849 type T = crate::ty::AliasRelationDirection;
850
851 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
852 use rustc_middle::ty::AliasRelationDirection::*;
853 match self {
854 Equate => crate::ty::AliasRelationDirection::Equate,
855 Subtype => crate::ty::AliasRelationDirection::Subtype,
856 }
857 }
858}
859
860841impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> {
861842 type T = crate::ty::TraitPredicate;
862843
compiler/rustc_resolve/src/error_helper.rs+5-7
......@@ -1469,13 +1469,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14691469 Scope::DeriveHelpers(expn_id) => {
14701470 let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
14711471 if filter_fn(res) {
1472 suggestions.extend(
1473 this.helper_attrs.get(&expn_id).into_iter().flatten().map(
1474 |&(ident, orig_ident_span, _)| {
1475 TypoSuggestion::new(ident.name, orig_ident_span, res)
1476 },
1477 ),
1478 );
1472 suggestions.extend(this.helper_attrs.get(&expn_id).into_flat_iter().map(
1473 |&(ident, orig_ident_span, _)| {
1474 TypoSuggestion::new(ident.name, orig_ident_span, res)
1475 },
1476 ));
14791477 }
14801478 }
14811479 Scope::DeriveHelpersCompat => {
compiler/rustc_resolve/src/ident.rs+9-2
......@@ -26,6 +26,7 @@ use crate::{
2626 Determinacy, ExternModule, Finalize, IdentKey, ImportKind, ImportSummary, LateDecl,
2727 LocalModule, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError,
2828 Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Symbol, Used, diagnostics,
29 module_to_string,
2930};
3031
3132#[derive(Copy, Clone)]
......@@ -1869,6 +1870,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18691870 module = Some(ModuleOrUniformRoot::Module(parent));
18701871 continue;
18711872 }
1873 let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
1874 let current_module = self.resolve_self(&mut ctxt, parent_scope.module);
1875 let current_module_path = module_to_string(current_module)
1876 .map_or_else(|| "crate".to_string(), |path| format!("crate::{path}"));
18721877 return PathResult::failed(
18731878 ident,
18741879 false,
......@@ -1877,8 +1882,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18771882 module,
18781883 || {
18791884 (
1880 "too many leading `super` keywords".to_string(),
1881 "there are too many leading `super` keywords".to_string(),
1885 format!(
1886 "too many leading `super` keywords within `{current_module_path}`"
1887 ),
1888 "this `super` would go above the crate root".to_string(),
18821889 None,
18831890 None,
18841891 )
compiler/rustc_resolve/src/lib.rs+1
......@@ -15,6 +15,7 @@
1515#![feature(default_field_values)]
1616#![feature(deref_patterns)]
1717#![feature(iter_intersperse)]
18#![feature(option_into_flat_iter)]
1819#![feature(rustc_attrs)]
1920#![feature(trim_prefix_suffix)]
2021#![recursion_limit = "256"]
compiler/rustc_session/src/lib.rs+1
......@@ -6,6 +6,7 @@
66#![feature(iter_intersperse)]
77#![feature(macro_derive)]
88#![feature(macro_metavar_expr)]
9#![feature(option_into_flat_iter)]
910#![feature(rustc_attrs)]
1011// To generate CodegenOptionsTargetModifiers and UnstableOptionsTargetModifiers enums
1112// with macro_rules, it is necessary to use recursive mechanic ("Incremental TT Munchers").
compiler/rustc_session/src/options.rs+1-1
......@@ -1621,7 +1621,7 @@ pub mod parse {
16211621 let mut seen_instruction_threshold = false;
16221622 let mut seen_skip_entry = false;
16231623 let mut seen_skip_exit = false;
1624 for option in v.into_iter().flat_map(|v| v.split(',')) {
1624 for option in v.map(|v| v.split(',')).into_flat_iter() {
16251625 match option {
16261626 "always" if !seen_always && !seen_never => {
16271627 options.always = true;
compiler/rustc_target/src/spec/mod.rs+1
......@@ -1687,6 +1687,7 @@ supported_targets! {
16871687 ("riscv32im-unknown-none-elf", riscv32im_unknown_none_elf),
16881688 ("riscv32ima-unknown-none-elf", riscv32ima_unknown_none_elf),
16891689 ("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
1690 ("riscv32imfc-unknown-none-elf", riscv32imfc_unknown_none_elf),
16901691 ("riscv32imc-esp-espidf", riscv32imc_esp_espidf),
16911692 ("riscv32imac-esp-espidf", riscv32imac_esp_espidf),
16921693 ("riscv32imafc-esp-espidf", riscv32imafc_esp_espidf),
compiler/rustc_target/src/spec/targets/riscv32imfc_unknown_none_elf.rs created+44
......@@ -0,0 +1,44 @@
1use crate::spec::{
2 Arch, Cc, LinkerFlavor, Lld, LlvmAbi, PanicStrategy, RelocModel, Target, TargetMetadata,
3 TargetOptions,
4};
5
6// Bare-metal RV32IMFC for cores that have hardware single-precision float (the `F`
7// extension, with the `ilp32f` ABI) but NO atomic ('a') extension.
8// This is `riscv32imafc-unknown-none-elf` MINUS the atomic extension, handled the
9// same way the in-tree `riscv32imc-unknown-none-elf` handles a no-`a` core:
10// `+forced-atomics` makes atomic load/store lower to plain ld/st (sound on a single
11// hart) while `atomic_cas = false` keeps RMW/CAS off — downstream crates use a
12// critical-section polyfill (e.g. portable-atomic) for those. No lr.w/sc.w/amo* are
13// ever emitted, so it does not trap on a core without the A extension.
14pub(crate) fn target() -> Target {
15 Target {
16 data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
17 llvm_target: "riscv32".into(),
18 metadata: TargetMetadata {
19 description: Some(
20 "Bare RISC-V (RV32IMFC ISA, hardware single-float, no atomics)".into(),
21 ),
22 tier: Some(3),
23 host_tools: Some(false),
24 std: Some(false),
25 },
26 pointer_width: 32,
27 arch: Arch::RiscV32,
28
29 options: TargetOptions {
30 linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
31 linker: Some("rust-lld".into()),
32 cpu: "generic-rv32".into(),
33 max_atomic_width: Some(32),
34 atomic_cas: false,
35 features: "+m,+f,+c,+forced-atomics".into(),
36 llvm_abiname: LlvmAbi::Ilp32f,
37 panic_strategy: PanicStrategy::Abort,
38 relocation_model: RelocModel::Static,
39 emit_debug_gdb_scripts: false,
40 eh_frame_header: false,
41 ..Default::default()
42 },
43 }
44}
compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs+64-52
......@@ -735,7 +735,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
735735 | ty::PredicateKind::Ambiguous
736736 | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature { .. })
737737 | ty::PredicateKind::NormalizesTo { .. }
738 | ty::PredicateKind::AliasRelate(..)
739738 | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => {
740739 span_bug!(
741740 span,
......@@ -1643,55 +1642,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
16431642 (None, error.err)
16441643 }
16451644 }
1646 ty::PredicateKind::AliasRelate(lhs, rhs, _) => {
1647 let derive_better_type_error =
1648 |alias_term: ty::AliasTerm<'tcx>, expected_term: ty::Term<'tcx>| {
1649 let ocx = ObligationCtxt::new(self);
1650
1651 let normalized_term = ocx.normalize(
1652 &ObligationCause::dummy(),
1653 obligation.param_env,
1654 Unnormalized::new_wip(
1655 alias_term.to_term(self.tcx, ty::IsRigid::No),
1656 ),
1657 );
1658
1659 if let Err(terr) = ocx.eq(
1660 &ObligationCause::dummy(),
1661 obligation.param_env,
1662 expected_term,
1663 normalized_term,
1664 ) {
1665 Some((terr, self.resolve_vars_if_possible(normalized_term)))
1666 } else {
1667 None
1668 }
1669 };
1670
1671 if let Some(lhs) = lhs.to_alias_term()
1672 && let ty::AliasTermKind::ProjectionTy { .. }
1673 | ty::AliasTermKind::ProjectionConst { .. } = lhs.kind
1674 && let Some((better_type_err, expected_term)) =
1675 derive_better_type_error(lhs, rhs)
1676 {
1677 (
1678 Some((lhs, self.resolve_vars_if_possible(expected_term), rhs)),
1679 better_type_err,
1680 )
1681 } else if let Some(rhs) = rhs.to_alias_term()
1682 && let ty::AliasTermKind::ProjectionTy { .. }
1683 | ty::AliasTermKind::ProjectionConst { .. } = rhs.kind
1684 && let Some((better_type_err, expected_term)) =
1685 derive_better_type_error(rhs, lhs)
1686 {
1687 (
1688 Some((rhs, self.resolve_vars_if_possible(expected_term), lhs)),
1689 better_type_err,
1690 )
1691 } else {
1692 (None, error.err)
1693 }
1694 }
16951645 _ => (None, error.err),
16961646 };
16971647
......@@ -2326,18 +2276,80 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
23262276 {
23272277 return false;
23282278 }
2279 let mut multi_span = MultiSpan::from_span(self.tcx.def_span(def_id));
23292280 let (desc, mention_castable) =
23302281 match (cand.self_ty().kind(), trait_pred.self_ty().skip_binder().kind()) {
23312282 (ty::FnPtr(..), ty::FnDef(..)) => {
23322283 (" implemented for fn pointer `", ", cast using `as`")
23332284 }
23342285 (ty::FnPtr(..), _) => (" implemented for fn pointer `", ""),
2335 _ => (" implemented for `", ""),
2286 _ => {
2287 let evaluate_obligations = || {
2288 let ocx = ObligationCtxt::new_with_diagnostics(self);
2289 self.enter_forall(trait_pred, |obligation_trait_ref| {
2290 let impl_args = self.fresh_args_for_item(DUMMY_SP, def_id);
2291 let impl_trait_ref = ocx.normalize(
2292 &ObligationCause::dummy(),
2293 param_env,
2294 ty::EarlyBinder::bind(self.tcx, cand)
2295 .instantiate(self.tcx, impl_args),
2296 );
2297 if ocx
2298 .eq(
2299 &ObligationCause::dummy(),
2300 param_env,
2301 obligation_trait_ref.trait_ref,
2302 impl_trait_ref,
2303 )
2304 .is_err()
2305 {
2306 return Vec::new();
2307 }
2308 ocx.register_obligations(
2309 self.tcx
2310 .predicates_of(def_id)
2311 .instantiate(self.tcx, impl_args)
2312 .into_iter()
2313 .map(|(clause, span)| {
2314 Obligation::new(
2315 self.tcx,
2316 ObligationCause::dummy_with_span(span),
2317 param_env,
2318 clause.skip_normalization(),
2319 )
2320 }),
2321 );
2322 ocx.try_evaluate_obligations()
2323 })
2324 };
2325 let failing_obligations =
2326 if !self.tcx.predicates_of(def_id).predicates.is_empty() {
2327 self.probe(|_| evaluate_obligations())
2328 } else {
2329 Vec::new()
2330 };
2331
2332 if failing_obligations.is_empty() {
2333 (" implemented for `", "")
2334 } else {
2335 for error in failing_obligations {
2336 multi_span.push_span_label(
2337 error.root_obligation.cause.span,
2338 format!(
2339 "unsatisfied requirement introduced here: `{}`",
2340 error.root_obligation.predicate,
2341 ),
2342 );
2343 }
2344
2345 (" conditionally implemented for `", "")
2346 }
2347 }
23362348 };
23372349 let trait_ = self.tcx.short_string(cand.print_trait_sugared(), err.long_ty_path());
23382350 let self_ty = self.tcx.short_string(cand.self_ty(), err.long_ty_path());
23392351 err.highlighted_span_help(
2340 self.tcx.def_span(def_id),
2352 multi_span,
23412353 vec![
23422354 StringPart::normal(format!("the trait `{trait_}` ")),
23432355 StringPart::highlighted("is"),
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs+1-1
......@@ -1613,7 +1613,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
16131613 _ => None,
16141614 };
16151615
1616 [typeck_results.expr_ty_adjusted_opt(expr)].into_iter().flatten().any(|expr_ty| {
1616 typeck_results.expr_ty_adjusted_opt(expr).is_some_and(|expr_ty| {
16171617 self.can_eq(obligation.param_env, expr_ty, old_self_ty)
16181618 || inner_old_self_ty
16191619 .is_some_and(|inner_ty| self.can_eq(obligation.param_env, expr_ty, inner_ty))
compiler/rustc_trait_selection/src/lib.rs+1
......@@ -19,6 +19,7 @@
1919#![feature(iter_intersperse)]
2020#![feature(iterator_try_reduce)]
2121#![feature(never_type)]
22#![feature(option_into_flat_iter)]
2223#![feature(try_blocks)]
2324#![feature(unwrap_infallible)]
2425#![feature(yeet_expr)]
compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs+1-20
......@@ -52,9 +52,6 @@ pub(super) fn fulfillment_error_for_no_solution<'tcx>(
5252 expected_ty,
5353 })
5454 }
55 ty::PredicateKind::AliasRelate(_, _, _) => {
56 FulfillmentErrorCode::Project(MismatchedProjectionTypes { err: TypeError::Mismatch })
57 }
5855 ty::PredicateKind::Subtype(pred) => {
5956 let (a, b) = infcx.enter_forall_and_leak_universe(
6057 obligation.predicate.kind().rebind((pred.a, pred.b)),
......@@ -264,8 +261,7 @@ impl<'tcx> BestObligation<'tcx> {
264261 let body_id = self.obligation.cause.body_id;
265262
266263 for obligation in wf::unnormalized_obligations(infcx, param_env, term, self.span(), body_id)
267 .into_iter()
268 .flatten()
264 .into_flat_iter()
269265 {
270266 let nested_goal = candidate.instantiate_proof_tree_for_nested_goal(
271267 GoalSource::Misc,
......@@ -544,21 +540,6 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
544540 self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
545541 }
546542
547 // alias-relate may fail because the lhs or rhs can't be normalized,
548 // and therefore is treated as rigid.
549 if let Some(ty::PredicateKind::AliasRelate(lhs, rhs, _)) = pred.kind().no_bound_vars() {
550 goal.infcx().visit_proof_tree_at_depth(
551 goal.goal().with(tcx, ty::ClauseKind::WellFormed(lhs)),
552 goal.depth() + 1,
553 self,
554 )?;
555 goal.infcx().visit_proof_tree_at_depth(
556 goal.goal().with(tcx, ty::ClauseKind::WellFormed(rhs)),
557 goal.depth() + 1,
558 self,
559 )?;
560 }
561
562543 self.detect_trait_error_in_higher_ranked_projection(goal)?;
563544
564545 ControlFlow::Break(self.obligation.clone())
compiler/rustc_trait_selection/src/traits/auto_trait.rs-1
......@@ -813,7 +813,6 @@ impl<'tcx> AutoTraitFinder<'tcx> {
813813 ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
814814 | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
815815 | ty::PredicateKind::NormalizesTo(..)
816 | ty::PredicateKind::AliasRelate(..)
817816 | ty::PredicateKind::DynCompatible(..)
818817 | ty::PredicateKind::Subtype(..)
819818 | ty::PredicateKind::Coerce(..)
compiler/rustc_trait_selection/src/traits/fulfill.rs-6
......@@ -461,9 +461,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
461461 ty::PredicateKind::NormalizesTo(..) => {
462462 bug!("NormalizesTo is only used by the new solver")
463463 }
464 ty::PredicateKind::AliasRelate(..) => {
465 bug!("AliasRelate is only used by the new solver")
466 }
467464 ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) => {
468465 unreachable!("unexpected higher ranked `UnstableFeature` goal")
469466 }
......@@ -535,9 +532,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
535532 ty::PredicateKind::NormalizesTo(..) => {
536533 bug!("NormalizesTo is only used by the new solver")
537534 }
538 ty::PredicateKind::AliasRelate(..) => {
539 bug!("AliasRelate is only used by the new solver")
540 }
541535 // Compute `ConstArgHasType` above the overflow check below.
542536 // This is because this is not ever a useful obligation to report
543537 // as the cause of an overflow.
compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs+2-4
......@@ -98,8 +98,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
9898 // From the full set of obligations, just filter down to the region relationships.
9999 for obligation in
100100 wf::unnormalized_obligations(ocx.infcx, param_env, arg, DUMMY_SP, CRATE_DEF_ID)
101 .into_iter()
102 .flatten()
101 .into_flat_iter()
103102 {
104103 let pred = ocx
105104 .deeply_normalize(
......@@ -125,8 +124,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
125124 | ty::PredicateKind::ConstEquate(..)
126125 | ty::PredicateKind::Ambiguous
127126 | ty::PredicateKind::NormalizesTo(..)
128 | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_))
129 | ty::PredicateKind::AliasRelate(..) => {}
127 | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) => {}
130128
131129 // We need to search through *all* WellFormed predicates
132130 ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs+8-4
......@@ -1030,10 +1030,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10301030 // supertraits.
10311031 let a_auto_traits: FxIndexSet<DefId> = a_data
10321032 .auto_traits()
1033 .chain(principal_def_id_a.into_iter().flat_map(|principal_def_id| {
1034 elaborate::supertrait_def_ids(self.tcx(), principal_def_id)
1035 .filter(|def_id| self.tcx().trait_is_auto(*def_id))
1036 }))
1033 .chain(
1034 principal_def_id_a
1035 .map(|principal_def_id| {
1036 elaborate::supertrait_def_ids(self.tcx(), principal_def_id)
1037 .filter(|def_id| self.tcx().trait_is_auto(*def_id))
1038 })
1039 .into_flat_iter(),
1040 )
10371041 .collect();
10381042 let auto_traits_compatible = b_data
10391043 .auto_traits()
compiler/rustc_trait_selection/src/traits/select/mod.rs+19-11
......@@ -771,10 +771,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
771771 Ok(EvaluatedToOkModuloRegions)
772772 }
773773
774 ty::PredicateKind::DynCompatible(_) => {
775 bug!(
776 "Obligation {obligation:?} should have been handled by fulfillment already."
777 )
774 ty::PredicateKind::DynCompatible(trait_def_id) => {
775 // `DynCompatible` obligations are only emitted as
776 // nested obligations of `WellFormed` goals. It is quite
777 // rare, but possible, that we encounter them during
778 // evaluation. See #158665 for more details here.
779 if self.tcx().is_dyn_compatible(trait_def_id) {
780 Ok(EvaluatedToOk)
781 } else {
782 Ok(EvaluatedToErr)
783 }
778784 }
779785
780786 ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
......@@ -972,9 +978,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
972978 ty::PredicateKind::NormalizesTo(..) => {
973979 bug!("NormalizesTo is only used by the new solver")
974980 }
975 ty::PredicateKind::AliasRelate(..) => {
976 bug!("AliasRelate is only used by the new solver")
977 }
978981 ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
979982 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
980983 let ct = self.infcx.shallow_resolve_const(ct);
......@@ -2594,10 +2597,15 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
25942597 // supertraits.
25952598 let a_auto_traits: FxIndexSet<DefId> = a_data
25962599 .auto_traits()
2597 .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
2598 elaborate::supertrait_def_ids(tcx, principal_def_id)
2599 .filter(|def_id| tcx.trait_is_auto(*def_id))
2600 }))
2600 .chain(
2601 a_data
2602 .principal_def_id()
2603 .map(|principal_def_id| {
2604 elaborate::supertrait_def_ids(tcx, principal_def_id)
2605 .filter(|def_id| tcx.trait_is_auto(*def_id))
2606 })
2607 .into_flat_iter(),
2608 )
26012609 .collect();
26022610
26032611 let upcast_principal = normalize_with_depth_to(
compiler/rustc_trait_selection/src/traits/vtable.rs+1-2
......@@ -188,8 +188,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
188188
189189/// Turns option of iterator into an iterator (this is just flatten)
190190fn maybe_iter<I: Iterator>(i: Option<I>) -> impl Iterator<Item = I::Item> {
191 // Flatten is bad perf-vise, we could probably implement a special case here that is better
192 i.into_iter().flatten()
191 i.into_flat_iter()
193192}
194193
195194fn has_own_existential_vtable_entries(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
compiler/rustc_traits/src/normalize_erasing_regions.rs-1
......@@ -70,7 +70,6 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool {
7070 | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
7171 | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_))
7272 | ty::PredicateKind::NormalizesTo(..)
73 | ty::PredicateKind::AliasRelate(..)
7473 | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
7574 | ty::PredicateKind::DynCompatible(..)
7675 | ty::PredicateKind::Subtype(..)
compiler/rustc_transmute/src/layout/dfa.rs+4-4
......@@ -257,15 +257,15 @@ where
257257 pub(crate) fn bytes_from(&self, start: State) -> impl Iterator<Item = (Byte, State)> {
258258 self.transitions
259259 .get(&start)
260 .into_iter()
261 .flat_map(|transitions| transitions.byte_transitions.iter())
260 .map(|transitions| transitions.byte_transitions.iter())
261 .into_flat_iter()
262262 }
263263
264264 pub(crate) fn refs_from(&self, start: State) -> impl Iterator<Item = (Reference<R, T>, State)> {
265265 self.transitions
266266 .get(&start)
267 .into_iter()
268 .flat_map(|transitions| transitions.ref_transitions.iter())
267 .map(|transitions| transitions.ref_transitions.iter())
268 .into_flat_iter()
269269 .map(|(r, s)| (*r, *s))
270270 }
271271
compiler/rustc_transmute/src/lib.rs+1
......@@ -1,6 +1,7 @@
11// tidy-alphabetical-start
22#![cfg_attr(test, feature(test))]
33#![feature(never_type)]
4#![feature(option_into_flat_iter)]
45// tidy-alphabetical-end
56
67pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set};
compiler/rustc_ty_utils/src/assoc.rs+2-2
......@@ -32,7 +32,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
3232 let item_def_id = trait_item_ref.owner_id.to_def_id();
3333 [item_def_id]
3434 .into_iter()
35 .chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied())
35 .chain(rpitit_items.get(&item_def_id).into_flat_iter().copied())
3636 }))
3737 }
3838 hir::ItemKind::Impl(impl_) => {
......@@ -44,7 +44,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
4444 let item_def_id = impl_item_ref.owner_id.to_def_id();
4545 [item_def_id]
4646 .into_iter()
47 .chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied())
47 .chain(rpitit_items.get(&item_def_id).into_flat_iter().copied())
4848 }))
4949 }
5050 _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"),
compiler/rustc_ty_utils/src/implied_bounds.rs+4-4
......@@ -176,13 +176,13 @@ fn impl_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Span>
176176 if let hir::ItemKind::Impl(impl_) = item.kind {
177177 let trait_args = impl_
178178 .of_trait
179 .into_iter()
180 .flat_map(|of_trait| of_trait.trait_ref.path.segments.last().unwrap().args().args)
179 .map(|of_trait| of_trait.trait_ref.path.segments.last().unwrap().args().args)
180 .into_flat_iter()
181181 .map(|arg| arg.span());
182182 let dummy_spans_for_default_args = impl_
183183 .of_trait
184 .into_iter()
185 .flat_map(|of_trait| iter::repeat(of_trait.trait_ref.path.span));
184 .map(|of_trait| iter::repeat(of_trait.trait_ref.path.span))
185 .into_flat_iter();
186186 iter::once(impl_.self_ty.span).chain(trait_args).chain(dummy_spans_for_default_args)
187187 } else {
188188 bug!("unexpected item for impl {def_id:?}: {item:?}")
compiler/rustc_ty_utils/src/layout.rs+1-2
......@@ -718,8 +718,7 @@ fn layout_of_uncached<'tcx>(
718718 let discriminants_iter = || {
719719 def.is_enum()
720720 .then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128)))
721 .into_iter()
722 .flatten()
721 .into_flat_iter()
723722 };
724723
725724 let maybe_unsized = def.is_struct()
compiler/rustc_ty_utils/src/lib.rs+1
......@@ -9,6 +9,7 @@
99#![feature(deref_patterns)]
1010#![feature(iterator_try_collect)]
1111#![feature(never_type)]
12#![feature(option_into_flat_iter)]
1213// tidy-alphabetical-end
1314
1415use rustc_middle::query::Providers;
compiler/rustc_type_ir/src/flags.rs-4
......@@ -443,10 +443,6 @@ impl<I: Interner> FlagComputation<I> {
443443 self.add_alias_term(alias);
444444 self.add_term(term);
445445 }
446 ty::PredicateKind::AliasRelate(t1, t2, _) => {
447 self.add_term(t1);
448 self.add_term(t2);
449 }
450446 ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_sym)) => {}
451447 ty::PredicateKind::Ambiguous => {}
452448 }
compiler/rustc_type_ir/src/generic_visit.rs-1
......@@ -198,7 +198,6 @@ trivial_impls!(
198198 usize,
199199 crate::PredicatePolarity,
200200 crate::BoundConstness,
201 crate::AliasRelationDirection,
202201 crate::DebruijnIndex,
203202 crate::solve::Certainty,
204203 crate::UniverseIndex,
compiler/rustc_type_ir/src/inherent.rs+1-3
......@@ -499,9 +499,7 @@ pub trait Predicate<I: Interner<Predicate = Self>>:
499499
500500 fn allow_normalization(self) -> bool {
501501 match self.kind().skip_binder() {
502 PredicateKind::Clause(ClauseKind::WellFormed(_)) | PredicateKind::AliasRelate(..) => {
503 false
504 }
502 PredicateKind::Clause(ClauseKind::WellFormed(_)) => false,
505503 PredicateKind::Clause(ClauseKind::Trait(_))
506504 | PredicateKind::Clause(ClauseKind::HostEffect(..))
507505 | PredicateKind::Clause(ClauseKind::RegionOutlives(_))
compiler/rustc_type_ir/src/macros.rs-1
......@@ -50,7 +50,6 @@ TrivialTypeTraversalImpls! {
5050 u32,
5151 u64,
5252 // tidy-alphabetical-start
53 crate::AliasRelationDirection,
5453 crate::BoundConstness,
5554 crate::DebruijnIndex,
5655 crate::PredicatePolarity,
compiler/rustc_type_ir/src/predicate_kind.rs+1-26
......@@ -2,7 +2,7 @@ use std::fmt;
22
33use derive_where::derive_where;
44#[cfg(feature = "nightly")]
5use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash, StableHash_NoContext};
5use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext};
66use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic};
77
88use crate::{self as ty, Interner};
......@@ -103,32 +103,10 @@ pub enum PredicateKind<I: Interner> {
103103 /// It is likely more useful to think of this as a function `normalizes_to(alias)`,
104104 /// whose return value is written into `term`.
105105 NormalizesTo(ty::NormalizesTo<I>),
106
107 /// Separate from `ClauseKind::Projection` which is used for normalization in new solver.
108 /// This predicate requires two terms to be equal to eachother.
109 ///
110 /// Only used for new solver.
111 AliasRelate(I::Term, I::Term, AliasRelationDirection),
112106}
113107
114108impl<I: Interner> Eq for PredicateKind<I> {}
115109
116#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
117#[cfg_attr(feature = "nightly", derive(StableHash, Encodable_NoContext, Decodable_NoContext))]
118pub enum AliasRelationDirection {
119 Equate,
120 Subtype,
121}
122
123impl std::fmt::Display for AliasRelationDirection {
124 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125 match self {
126 AliasRelationDirection::Equate => write!(f, "=="),
127 AliasRelationDirection::Subtype => write!(f, "<:"),
128 }
129 }
130}
131
132110impl<I: Interner> fmt::Debug for ClauseKind<I> {
133111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134112 match self {
......@@ -161,9 +139,6 @@ impl<I: Interner> fmt::Debug for PredicateKind<I> {
161139 PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({c1:?}, {c2:?})"),
162140 PredicateKind::Ambiguous => write!(f, "Ambiguous"),
163141 PredicateKind::NormalizesTo(p) => p.fmt(f),
164 PredicateKind::AliasRelate(t1, t2, dir) => {
165 write!(f, "AliasRelate({t1:?}, {dir:?}, {t2:?})")
166 }
167142 }
168143 }
169144}
compiler/rustc_type_ir/src/relate/combine.rs+70-70
......@@ -38,8 +38,7 @@ where
3838 obligations: impl IntoIterator<Item: Upcast<I, I::Predicate>>,
3939 );
4040
41 /// Register `AliasRelate` obligation(s) that both types must be related to each other.
42 fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty);
41 fn ambient_variance(&self) -> ty::Variance;
4342}
4443
4544pub fn super_combine_tys<Infcx, I, R>(
......@@ -115,60 +114,69 @@ where
115114 panic!("We do not expect to encounter `Fresh` variables in the new solver")
116115 }
117116
118 (ty::Alias(is_rigid_a, _), ty::Alias(is_rigid_b, _)) if infcx.next_trait_solver() => {
119 match (is_rigid_a, is_rigid_b) {
120 (ty::IsRigid::Yes, ty::IsRigid::Yes) => structurally_relate_tys(relation, a, b),
121 _ => match relation.structurally_relate_aliases() {
122 StructurallyRelateAliases::Yes => structurally_relate_tys(relation, a, b),
123 StructurallyRelateAliases::No => {
124 relation.register_alias_relate_predicate(a, b);
125 Ok(a)
126 }
127 },
128 }
129 }
130
131 (other, ty::Alias(is_rigid, _)) | (ty::Alias(is_rigid, _), other)
132 if infcx.next_trait_solver() =>
117 (ty::Alias(ty::IsRigid::No, alias), _) | (_, ty::Alias(ty::IsRigid::No, alias))
118 if infcx.next_trait_solver()
119 && let StructurallyRelateAliases::No = relation.structurally_relate_aliases() =>
133120 {
134 if let StructurallyRelateAliases::No = relation.structurally_relate_aliases()
135 && is_rigid == ty::IsRigid::No
136 {
137 relation.register_alias_relate_predicate(a, b);
138 Ok(a)
139 } else {
140 match other {
141 ty::Infer(infer_ty) => match infer_ty {
142 // Normally, we shouldn't be combining an infer ty with an alias here. But
143 // when we evaluate a `Projection(assoc_ty, expected)` goal, we normalize
144 // the projection term and structurally equate it with the expected term. If
145 // the normalized term is an alias type and the expected term is a ty var,
146 // the ty var just instantiated with the alias type without combining them.
147 // However, if the expected term is either an int var or a float var, e.g.,
148 // when the expected term is an int literal that only can be fully inferred
149 // after the fallback, they are passed to this function because int/float
150 // vars can't be instantiated. As we can't structurally relate infer ty with
151 // another type, we just error them out here instead.
152 ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(_) => {
153 Err(TypeError::Sorts(ExpectedFound::new(a, b)))
154 }
155
156 ty::InferTy::TyVar(_)
157 | ty::InferTy::FreshTy(_)
158 | ty::InferTy::FreshIntTy(_)
159 | ty::InferTy::FreshFloatTy(_) => unreachable!(),
160 },
161 _ => structurally_relate_tys(relation, a, b),
121 // If both sides are aliases, arbitrarily do the LHS first
122 let terms_are_inverted = !matches!(a.kind(), ty::Alias(ty::IsRigid::No, _));
123 let other = if terms_are_inverted { a } else { b };
124 match (relation.ambient_variance(), terms_are_inverted) {
125 (ty::Invariant, _) => relation.register_predicates([ty::ProjectionPredicate {
126 projection_term: alias.into(),
127 term: other.into(),
128 }]),
129 (ty::Covariant, false) | (ty::Contravariant, true) => {
130 // Generate a new var to represent `alias <: other`
131 // with `alias == ?A && ?A <: other`
132 let new_var = infcx.next_ty_infer();
133 relation.register_predicates([
134 ty::PredicateKind::Clause(ty::ClauseKind::Projection(
135 ty::ProjectionPredicate {
136 projection_term: alias.into(),
137 term: new_var.into(),
138 },
139 )),
140 ty::PredicateKind::Subtype(ty::SubtypePredicate {
141 a_is_expected: !terms_are_inverted,
142 a: new_var,
143 b: other,
144 }),
145 ]);
146 }
147 (ty::Contravariant, false) | (ty::Covariant, true) => {
148 // a :> b is b <: a
149 let new_var = infcx.next_ty_infer();
150 relation.register_predicates([
151 ty::PredicateKind::Clause(ty::ClauseKind::Projection(
152 ty::ProjectionPredicate {
153 projection_term: alias.into(),
154 term: new_var.into(),
155 },
156 )),
157 ty::PredicateKind::Subtype(ty::SubtypePredicate {
158 a_is_expected: terms_are_inverted,
159 a: other,
160 b: new_var,
161 }),
162 ]);
163 }
164 (ty::Bivariant, _) => {
165 unreachable!(
166 "cannot handle bivariant aliases in register_projection_with_variance"
167 )
162168 }
163169 }
170 Ok(a)
164171 }
165172
166173 // All other cases of inference are errors
167174 (ty::Infer(_), _) | (_, ty::Infer(_)) => Err(TypeError::Sorts(ExpectedFound::new(a, b))),
168175
169176 (ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. }), _)
170 | (_, ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. })) => {
171 assert!(!infcx.next_trait_solver());
177 | (_, ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. }))
178 if !infcx.next_trait_solver() =>
179 {
172180 match infcx.typing_mode_raw().assert_not_erased() {
173181 // During coherence, opaque types should be treated as *possibly*
174182 // equal to any other type. This is an
......@@ -239,32 +247,24 @@ where
239247 Ok(a)
240248 }
241249
242 (ty::ConstKind::Alias(ty::IsRigid::Yes, _), ty::ConstKind::Alias(ty::IsRigid::Yes, _))
243 if (infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver()) =>
250 (ty::ConstKind::Alias(ty::IsRigid::No, alias), _)
251 | (_, ty::ConstKind::Alias(ty::IsRigid::No, alias))
252 if (infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver())
253 && let StructurallyRelateAliases::No = relation.structurally_relate_aliases() =>
244254 {
245 structurally_relate_consts(relation, a, b)
246 }
247
248 (ty::ConstKind::Alias(..), _) | (_, ty::ConstKind::Alias(..))
249 if infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver() =>
250 {
251 match relation.structurally_relate_aliases() {
252 StructurallyRelateAliases::No => {
253 relation.register_predicates([if infcx.next_trait_solver() {
254 ty::PredicateKind::AliasRelate(
255 a.into(),
256 b.into(),
257 ty::AliasRelationDirection::Equate,
258 )
259 } else {
260 ty::PredicateKind::ConstEquate(a, b)
261 }]);
262
263 Ok(b)
264 }
265 StructurallyRelateAliases::Yes => structurally_relate_consts(relation, a, b),
255 if infcx.next_trait_solver() {
256 let other = if matches!(a.kind(), ty::ConstKind::Alias(..)) { b } else { a };
257 relation.register_predicates([ty::ProjectionPredicate {
258 projection_term: alias.into(),
259 term: other.into(),
260 }])
261 } else {
262 relation.register_predicates([ty::PredicateKind::ConstEquate(a, b)]);
266263 }
264
265 Ok(b)
267266 }
267
268268 _ => structurally_relate_consts(relation, a, b),
269269 }
270270}
compiler/rustc_type_ir/src/relate/solver_relating.rs+2-22
......@@ -383,27 +383,7 @@ where
383383 self.goals.extend(obligations);
384384 }
385385
386 fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty) {
387 self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
388 ty::Covariant => ty::PredicateKind::AliasRelate(
389 a.into(),
390 b.into(),
391 ty::AliasRelationDirection::Subtype,
392 ),
393 // a :> b is b <: a
394 ty::Contravariant => ty::PredicateKind::AliasRelate(
395 b.into(),
396 a.into(),
397 ty::AliasRelationDirection::Subtype,
398 ),
399 ty::Invariant => ty::PredicateKind::AliasRelate(
400 a.into(),
401 b.into(),
402 ty::AliasRelationDirection::Equate,
403 ),
404 ty::Bivariant => {
405 unreachable!("Expected bivariance to be handled in relate_with_variance")
406 }
407 })]);
386 fn ambient_variance(&self) -> ty::Variance {
387 self.ambient_variance
408388 }
409389}
library/core/src/attribute_docs.rs+47-33
......@@ -8,10 +8,10 @@
88///
99/// This is most common on types that represent an important state or outcome. For example,
1010/// [`Result`] is marked `#[must_use]` because ignoring an error value can hide a failed operation.
11/// In the following example, the returned `Result` is the only sign that writing the message
11/// In the following example, the returned [`Result`] is the only sign that writing the message
1212/// might have failed:
1313///
14/// ```rust
14/// ```
1515/// # #![allow(unused_must_use)]
1616/// fn write_message() -> std::io::Result<()> {
1717/// // Write the message...
......@@ -21,7 +21,7 @@
2121/// write_message();
2222/// ```
2323///
24/// Ignoring that `Result` triggers this warning:
24/// Ignoring that [`Result`] triggers this warning:
2525///
2626/// ```text
2727/// warning: unused `Result` that must be used
......@@ -36,7 +36,7 @@
3636/// You can also place `#[must_use]` on a function, method, or trait declaration. On a function or
3737/// method, the warning is tied to ignoring that call's return value:
3838///
39/// ```rust
39/// ```
4040/// # #![allow(unused_must_use)]
4141/// #[must_use]
4242/// fn make_token() -> String {
......@@ -53,7 +53,7 @@
5353///
5454/// The attribute can include a message explaining what the caller should do with the value:
5555///
56/// ```rust
56/// ```
5757/// # #![allow(dead_code)]
5858/// #[must_use = "call `.finish()` to complete the operation"]
5959/// fn start_operation() -> Operation {
......@@ -65,7 +65,7 @@
6565///
6666/// If intentionally ignoring the value is correct, bind it to `_` or call [`drop`]:
6767///
68/// ```rust
68/// ```
6969/// # #[must_use]
7070/// # fn make_token() -> String {
7171/// # String::from("token")
......@@ -80,8 +80,6 @@
8080///
8181/// For more information, see the Reference on [the `must_use` attribute].
8282///
83/// [`Result`]: result::Result
84/// [`Future`]: future::Future
8583/// [`unused_must_use`]: ../rustc/lints/listing/warn-by-default.html#unused-must-use
8684/// [the `must_use` attribute]: ../reference/attributes/diagnostics.html#the-must_use-attribute
8785mod must_use_attribute {}
......@@ -90,9 +88,9 @@ mod must_use_attribute {}
9088//
9189/// The `allow` attribute suppresses lint diagnostics that would otherwise produce
9290/// warnings or errors. It can be used on any lint or lint group (except those
93/// set to `forbid`).
91/// set to [`forbid`]).
9492///
95/// ```rust
93/// ```
9694/// #[allow(dead_code)]
9795/// fn unused_function() {
9896/// // ...
......@@ -119,7 +117,7 @@ mod must_use_attribute {}
119117///
120118/// Multiple lints can be set to `allow` at once with commas:
121119///
122/// ```rust
120/// ```
123121/// #[allow(unused_variables, unused_mut)]
124122/// fn main() {
125123/// let mut x: u32 = 42;
......@@ -128,12 +126,12 @@ mod must_use_attribute {}
128126///
129127/// This is mostly used to prevent lint warnings or errors while still under development.
130128///
131/// It cannot override a lint that has been set to `forbid`.
129/// It cannot override a lint that has been set to [`forbid`].
132130///
133131/// It's also important to consider that overusing `allow` could make code harder to maintain
134132/// and possibly hide issues. To mitigate this issue, using the `expect` attribute is preferred.
135133///
136/// `allow` can be overridden by `warn`, `deny`, and `forbid`.
134/// `allow` can be overridden by [`warn`], [`deny`], and [`forbid`].
137135///
138136/// The lint checks supported by rustc can be found via `rustc -W help`,
139137/// along with their default settings and are documented in [the `rustc` book].
......@@ -143,6 +141,9 @@ mod must_use_attribute {}
143141/// For more information, see the Reference on [the `allow` attribute].
144142///
145143/// [the `allow` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes
144/// [`forbid`]: ./attribute.forbid.html
145/// [`warn`]: ./attribute.warn.html
146/// [`deny`]: ./attribute.deny.html
146147mod allow_attribute {}
147148
148149#[doc(attribute = "cfg")]
......@@ -152,7 +153,7 @@ mod allow_attribute {}
152153/// The `cfg` attribute allows compiling an item under specific conditions, otherwise it
153154/// will be ignored.
154155///
155/// ```rust
156/// ```
156157/// // Only compiles this function for Linux.
157158/// #[cfg(target_os = "linux")]
158159/// fn platform_specific() {
......@@ -169,19 +170,20 @@ mod allow_attribute {}
169170/// Depending on the platform you're targeting, only one of these two functions will be considered
170171/// during the compilation.
171172///
172/// Conditions can also be combined with `all(...)`, `any(...)`, and `not(...)`.
173/// Conditions can also be combined with `all(...)`, `any(...)`, and `not(...)`:
173174///
174175/// * `all`: True if all given predicates are true.
175176/// * `any`: True if at least one of the given predicates is true.
176177/// * `not`: True if the predicate is false and false if the predicate is true.
177178///
178/// ```rust
179/// ```
179180/// #[cfg(all(unix, target_pointer_width = "64"))]
180181/// fn unix_64bit() {
182/// // ...
181183/// }
182184/// ```
183185///
184/// If you want to use this mechanism in an `if` condition in your code, you
186/// If you want to use this mechanism in an [`if`] condition in your code, you
185187/// can use the [`cfg!`] macro. To conditionally apply an attribute,
186188/// see [`cfg_attr`].
187189///
......@@ -189,6 +191,7 @@ mod allow_attribute {}
189191///
190192/// [`cfg_attr`]: ../reference/conditional-compilation.html#the-cfg_attr-attribute
191193/// [the `cfg` attribute]: ../reference/conditional-compilation.html#the-cfg-attribute
194/// [`if`]: ./keyword.if.html
192195mod cfg_attribute {}
193196
194197#[doc(attribute = "deny")]
......@@ -196,16 +199,16 @@ mod cfg_attribute {}
196199/// Emits an error, preventing the compilation from finishing, when a lint check has failed.
197200/// This is useful for enforcing rules or preventing certain patterns:
198201///
199/// ```rust,compile_fail
202/// ```compile_fail
200203/// #[deny(unused)]
201204/// fn foo() {
202205/// let x = 42; // Emits an error because x is unused.
203206/// }
204207/// ```
205208///
206/// `deny` can be overridden by `allow`, `warn`, and `forbid`:
209/// `deny` can be overridden by [`allow`], [`warn`], and [`forbid`]:
207210///
208/// ```rust
211/// ```
209212/// #![deny(unused)]
210213///
211214/// #[allow(unused)] // We override the `deny` for this function.
......@@ -216,7 +219,7 @@ mod cfg_attribute {}
216219///
217220/// Multiple lints can also be set to `deny` at once:
218221///
219/// ```rust,compile_fail
222/// ```compile_fail
220223/// #![deny(unused_imports, unused_variables)]
221224/// use std::collections::*;
222225///
......@@ -233,20 +236,24 @@ mod cfg_attribute {}
233236/// For more information, see the Reference on [the `deny` attribute].
234237///
235238/// [the `deny` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes
239/// [`forbid`]: ./attribute.forbid.html
240/// [`allow`]: ./attribute.allow.html
241/// [`warn`]: ./attribute.warn.html
242/// [`deny`]: ./attribute.deny.html
236243mod deny_attribute {}
237244
238245#[doc(attribute = "forbid")]
239246//
240247/// Emits an error, preventing the compilation from finishing, when a lint check has failed.
241248///
242/// A lint set to `forbid` cannot be overridden by `allow` or `warn`.
249/// A lint set to `forbid` cannot be overridden by [`allow`] or [`warn`].
243250/// Attempting either will result in a compilation error. Writing `#[deny(...)]` on the same lint inside a
244251/// `forbid` scope is permitted, but has no effect; the lint remains at the `forbid` level.
245252///
246253/// This is useful for enforcing strict policies that should not be relaxed
247254/// anywhere in the codebase. Example:
248255///
249/// ```rust
256/// ```
250257/// #![forbid(unsafe_code)]
251258///
252259/// // This would cause a compilation error if uncommented:
......@@ -255,7 +262,7 @@ mod deny_attribute {}
255262///
256263/// Multiple lints can be set to `forbid` at once:
257264///
258/// ```rust
265/// ```
259266/// #![forbid(unsafe_code, unused)]
260267/// ```
261268///
......@@ -267,6 +274,8 @@ mod deny_attribute {}
267274/// For more information, see the Reference on [the `forbid` attribute].
268275///
269276/// [the `forbid` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes
277/// [`allow`]: ./attribute.allow.html
278/// [`warn`]: ./attribute.warn.html
270279mod forbid_attribute {}
271280
272281#[doc(attribute = "deprecated")]
......@@ -279,15 +288,16 @@ mod forbid_attribute {}
279288///
280289/// Example:
281290///
282/// ```rust
291/// ```
283292/// #[deprecated(since = "1.0.0", note = "Use bar instead")]
284293/// struct Foo;
285294/// struct Bar;
286295/// ```
287296///
288/// `deprecated` attribute helps developers transition away from old code by providing warnings when
289/// deprecated items are used. Note that during `Cargo` builds, warnings on dependencies get silenced
290/// by default, so you may not see a deprecation warning unless you build that dependency directly.
297/// The `deprecated` attribute helps developers transition away from old code by providing warnings
298/// when deprecated items are used. Note that during `Cargo` builds, warnings on dependencies get
299/// silenced by default, so you may not see a deprecation warning unless you build that dependency
300/// directly.
291301///
292302/// For more information, see the Reference on [the `deprecated` attribute].
293303///
......@@ -298,12 +308,13 @@ mod deprecated_attribute {}
298308//
299309/// Emits a warning during compilation when a lint check failed.
300310///
301/// Unlike `deny` or `forbid`, `warn` does not produce a hard error: the compilation continues, but
302/// the compiler emits a warning message. `warn` can be overridden by `allow`, `deny`, and `forbid`.
311/// Unlike [`deny`] or [`forbid`], `warn` does not produce a hard error: the compilation
312/// continues, but the compiler emits a warning message. `warn` can be overridden by [`allow`],
313/// [`deny`], and [`forbid`].
303314///
304315/// Example:
305316///
306/// ```rust,compile_fail
317/// ```compile_fail
307318/// #![allow(unused)]
308319///
309320/// #[warn(unused)] // We override the allowed `unused` lint.
......@@ -315,11 +326,11 @@ mod deprecated_attribute {}
315326///
316327///
317328/// Many lints, including `unused`, are already set to `warn` by default so this attribute is
318/// mainly useful for lints that are normally `allow` by default.
329/// mainly useful for lints that are normally [`allow`] by default.
319330///
320331/// Multiple lints can be set to `warn` at once:
321332///
322/// ```rust,compile_fail
333/// ```compile_fail
323334/// #[warn(unused_mut, unused_variables)]
324335/// fn main() {
325336/// let mut x = 42;
......@@ -334,4 +345,7 @@ mod deprecated_attribute {}
334345/// For more information, see the Reference on [the `warn` attribute].
335346///
336347/// [the `warn` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes
348/// [`allow`]: ./attribute.allow.html
349/// [`deny`]: ./attribute.deny.html
350/// [`forbid`]: ./attribute.forbid.html
337351mod warn_attribute {}
library/core/src/intrinsics/mod.rs+10-10
......@@ -818,19 +818,19 @@ pub const fn forget<T: ?Sized>(_: T);
818818///
819819/// // This is how the standard library does it. This is the best method, if
820820/// // you need to do something like this
821/// fn split_at_stdlib<T>(slice: &mut [T], mid: usize)
821/// fn split_at_stdlib<T>(to_split: &mut [T], mid: usize)
822822/// -> (&mut [T], &mut [T]) {
823/// let len = slice.len();
823/// let len = to_split.len();
824824/// assert!(mid <= len);
825825/// unsafe {
826/// let ptr = slice.as_mut_ptr();
827/// // This now has three mutable references pointing at the same
828/// // memory. `slice`, the rvalue ret.0, and the rvalue ret.1.
829/// // `slice` is never used after `let ptr = ...`, and so one can
830/// // treat it as "dead", and therefore, you only have two real
831/// // mutable slices.
832/// (slice::from_raw_parts_mut(ptr, mid),
833/// slice::from_raw_parts_mut(ptr.add(mid), len - mid))
826/// let ptr = to_split.as_mut_ptr();
827/// let fst = slice::from_raw_parts_mut(ptr, mid);
828/// let snd = slice::from_raw_parts_mut(ptr.add(mid), len - mid);
829/// // The function now has three mutable references to overlapping memory:
830/// // `to_split`, `fst`, and `snd`.
831/// // `to_split` is never used after `let ptr = ...` so it can be treated as "dead".
832/// // This leaves two "live" mutable slice references, `fst` and `snd`, with no overlap.
833/// (fst, snd)
834834/// }
835835/// }
836836/// ```
library/core/src/ptr/mod.rs+19-21
......@@ -300,27 +300,25 @@
300300//! represent the tagged pointer as an actual pointer and not a `usize`*. For instance:
301301//!
302302//! ```
303//! unsafe {
304//! // A flag we want to pack into our pointer
305//! static HAS_DATA: usize = 0x1;
306//! static FLAG_MASK: usize = !HAS_DATA;
307//!
308//! // Our value, which must have enough alignment to have spare least-significant-bits.
309//! let my_precious_data: u32 = 17;
310//! assert!(align_of::<u32>() > 1);
311//!
312//! // Create a tagged pointer
313//! let ptr = &my_precious_data as *const u32;
314//! let tagged = ptr.map_addr(|addr| addr | HAS_DATA);
315//!
316//! // Check the flag:
317//! if tagged.addr() & HAS_DATA != 0 {
318//! // Untag and read the pointer
319//! let data = *tagged.map_addr(|addr| addr & FLAG_MASK);
320//! assert_eq!(data, 17);
321//! } else {
322//! unreachable!()
323//! }
303//! // A flag we want to pack into our pointer
304//! static HAS_DATA: usize = 0x1;
305//! static FLAG_MASK: usize = !HAS_DATA;
306//!
307//! // Our value, which must have enough alignment to have spare least-significant-bits.
308//! let my_precious_data: u32 = 17;
309//! assert!(align_of::<u32>() > 1);
310//!
311//! // Create a tagged pointer
312//! let ptr = &my_precious_data as *const u32;
313//! let tagged = ptr.map_addr(|addr| addr | HAS_DATA);
314//!
315//! // Check the flag:
316//! if tagged.addr() & HAS_DATA != 0 {
317//! // Untag and read the pointer
318//! let data = unsafe { *tagged.map_addr(|addr| addr & FLAG_MASK) };
319//! assert_eq!(data, 17);
320//! } else {
321//! unreachable!()
324322//! }
325323//! ```
326324//!
library/std/src/sys/process/unix/vxworks.rs+11-1
......@@ -124,7 +124,17 @@ impl Command {
124124 Ok(t) => unsafe {
125125 let mut status = 0 as c_int;
126126 libc::waitpid(t.0.pid, &mut status, 0);
127 libc::exit(0);
127 // If the task was killed by a signal, terminate the same way by
128 // restoring the default disposition and resending it to ourselves.
129 if libc::WIFSIGNALED(status) {
130 let signal = libc::WTERMSIG(status);
131 libc::signal(signal, libc::SIG_DFL);
132 libc::kill(libc::getpid(), signal);
133 // The signal should have already terminated us; abort if it
134 // was blocked or ignored.
135 libc::abort();
136 }
137 libc::exit(libc::WEXITSTATUS(status));
128138 },
129139 Err(e) => e,
130140 }
src/ci/run.sh-8
......@@ -79,14 +79,6 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-units-std=1"
7979# of our CPU resources.
8080RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set dist.compression-profile=balanced"
8181
82# When building for mingw, limit the number of parallel linker jobs during
83# the LLVM build, as not to run out of memory.
84# This is an attempt to fix the spurious build error tracked by
85# https://github.com/rust-lang/rust/issues/108227.
86if isKnownToBeMingwBuild; then
87 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.link-jobs=1"
88fi
89
9082# Only produce xz tarballs on CI. gz tarballs will be generated by the release
9183# process by recompressing the existing xz ones. This decreases the storage
9284# space required for CI artifacts.
src/doc/rustc/src/platform-support.md+1
......@@ -401,6 +401,7 @@ target | std | host | notes
401401`riscv32gc-unknown-linux-musl` | ? | | RISC-V Linux (kernel 5.4, musl 1.2.5)
402402[`riscv32im-risc0-zkvm-elf`](platform-support/riscv32im-risc0-zkvm-elf.md) | ? | | RISC Zero's zero-knowledge Virtual Machine (RV32IM ISA)
403403[`riscv32ima-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IMA ISA)
404[`riscv32imfc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IMFC ISA, hardware single-float, no atomics)
404405[`riscv32imac-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF
405406[`riscv32imac-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 32bit with NuttX
406407[`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA)
src/doc/rustc/src/platform-support/riscv32-unknown-none-elf.md+15-2
......@@ -1,4 +1,4 @@
1# `riscv32{i,im,ima,imc,imac,imafc}-unknown-none-elf`
1# `riscv32{i,im,ima,imc,imfc,imac,imafc}-unknown-none-elf`
22
33**Tier: 2**
44
......@@ -6,12 +6,25 @@ Bare-metal target for RISC-V CPUs with the RV32I, RV32IM, RV32IMC, RV32IMAFC and
66
77**Tier: 3**
88
9Bare-metal target for RISC-V CPUs with the RV32IMA ISA.
9Bare-metal target for RISC-V CPUs with the RV32IMA and RV32IMFC ISAs.
10
11The `riscv32imfc-unknown-none-elf` target covers RV32IMFC cores that have
12hardware single-precision floating point (the `F` extension, using the `ilp32f`
13ABI) but *no* atomic (`A`) extension. Like `riscv32imc-unknown-none-elf`, it is
14built with `+forced-atomics`: atomic loads/stores lower to plain loads/stores
15(sound on a single hart) and `lr`/`sc`/`amo*` instructions are never emitted, so
16it does not trap on a core without the `A` extension. Compare-and-swap and other
17read-modify-write atomics are disabled (`atomic_cas = false`); downstream crates
18that need them use a critical-section polyfill (e.g. `portable-atomic`).
1019
1120## Target maintainers
1221
1322* Rust Embedded Working Group, [RISC-V team](https://github.com/rust-embedded/wg#the-risc-v-team)
1423
24The `riscv32imfc-unknown-none-elf` target is additionally maintained by:
25
26* [@sanchuanhehe](https://github.com/sanchuanhehe)
27
1528## Requirements
1629
1730The target is cross-compiled, and uses static linking. No external toolchain
src/llvm-project+1-1
......@@ -1 +1 @@
1Subproject commit 3c3f13025bf9f99bb2a757eb37dad4f09e7d6c36
1Subproject commit a04c1eced55f2f3ea8dbd3d17db0b6df271c0809
src/tools/test-float-parse/Cargo.lock deleted-75
......@@ -1,75 +0,0 @@
1# This file is automatically @generated by Cargo.
2# It is not intended for manual editing.
3version = 3
4
5[[package]]
6name = "cfg-if"
7version = "1.0.0"
8source = "registry+https://github.com/rust-lang/crates.io-index"
9checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
10
11[[package]]
12name = "getrandom"
13version = "0.2.10"
14source = "registry+https://github.com/rust-lang/crates.io-index"
15checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
16dependencies = [
17 "cfg-if",
18 "libc",
19 "wasi",
20]
21
22[[package]]
23name = "libc"
24version = "0.2.147"
25source = "registry+https://github.com/rust-lang/crates.io-index"
26checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
27
28[[package]]
29name = "ppv-lite86"
30version = "0.2.17"
31source = "registry+https://github.com/rust-lang/crates.io-index"
32checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
33
34[[package]]
35name = "rand"
36version = "0.8.5"
37source = "registry+https://github.com/rust-lang/crates.io-index"
38checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
39dependencies = [
40 "libc",
41 "rand_chacha",
42 "rand_core",
43]
44
45[[package]]
46name = "rand_chacha"
47version = "0.3.1"
48source = "registry+https://github.com/rust-lang/crates.io-index"
49checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
50dependencies = [
51 "ppv-lite86",
52 "rand_core",
53]
54
55[[package]]
56name = "rand_core"
57version = "0.6.4"
58source = "registry+https://github.com/rust-lang/crates.io-index"
59checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
60dependencies = [
61 "getrandom",
62]
63
64[[package]]
65name = "test-float-parse"
66version = "0.1.0"
67dependencies = [
68 "rand",
69]
70
71[[package]]
72name = "wasi"
73version = "0.11.0+wasi-snapshot-preview1"
74source = "registry+https://github.com/rust-lang/crates.io-index"
75checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
tests/assembly-llvm/targets/targets-elf.rs+3
......@@ -508,6 +508,9 @@
508508//@ revisions: riscv32imc_unknown_none_elf
509509//@ [riscv32imc_unknown_none_elf] compile-flags: --target riscv32imc-unknown-none-elf
510510//@ [riscv32imc_unknown_none_elf] needs-llvm-components: riscv
511//@ revisions: riscv32imfc_unknown_none_elf
512//@ [riscv32imfc_unknown_none_elf] compile-flags: --target riscv32imfc-unknown-none-elf
513//@ [riscv32imfc_unknown_none_elf] needs-llvm-components: riscv
511514//@ revisions: riscv64_linux_android
512515//@ [riscv64_linux_android] compile-flags: --target riscv64-linux-android
513516//@ [riscv64_linux_android] needs-llvm-components: riscv
tests/ui/associated-inherent-types/next-solver-unsatisfied-bounds-inherent-tait.rs created+22
......@@ -0,0 +1,22 @@
1//@ compile-flags: -Znext-solver=globally
2
3#![feature(inherent_associated_types)]
4#![feature(type_alias_impl_trait)]
5#![allow(incomplete_features)]
6
7struct Foo<T>(T);
8
9impl Foo<Vec<[u32]>> {
10 //~^ ERROR the size for values of type `[u32]` cannot be known at compilation time
11 type Assoc = u32;
12}
13
14type Tait = impl Sized;
15
16#[define_opaque(Tait)]
17fn bar() {
18 let _: Foo<Tait>::Assoc = 42;
19 //~^ ERROR the associated type `Assoc` exists for `Foo<Tait>`, but its trait bounds were not satisfied
20}
21
22fn main() {}
tests/ui/associated-inherent-types/next-solver-unsatisfied-bounds-inherent-tait.stderr created+22
......@@ -0,0 +1,22 @@
1error[E0277]: the size for values of type `[u32]` cannot be known at compilation time
2 --> $DIR/next-solver-unsatisfied-bounds-inherent-tait.rs:9:10
3 |
4LL | impl Foo<Vec<[u32]>> {
5 | ^^^^^^^^^^ doesn't have a size known at compile-time
6 |
7 = help: the trait `Sized` is not implemented for `[u32]`
8note: required by an implicit `Sized` bound in `Vec`
9 --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
10
11error: the associated type `Assoc` exists for `Foo<Tait>`, but its trait bounds were not satisfied
12 --> $DIR/next-solver-unsatisfied-bounds-inherent-tait.rs:18:23
13 |
14LL | struct Foo<T>(T);
15 | ------------- associated type `Assoc` not found for this struct
16...
17LL | let _: Foo<Tait>::Assoc = 42;
18 | ^^^^^ associated type cannot be referenced on `Foo<Tait>` due to unsatisfied trait bounds
19
20error: aborting due to 2 previous errors
21
22For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/redundant-derive-note-on-unimplemented.stderr+3-1
......@@ -7,11 +7,13 @@ LL | println!("{:?}", S(X));
77 | required by this formatting parameter
88 |
99 = help: the trait `Debug` is not implemented for `X`
10help: the trait `Debug` is implemented for `S<T>`
10help: the trait `Debug` is conditionally implemented for `S<T>`
1111 --> $DIR/redundant-derive-note-on-unimplemented.rs:8:10
1212 |
1313LL | #[derive(Debug)]
1414 | ^^^^^
15LL | struct S<T>(T);
16 | - unsatisfied requirement introduced here: `X: Debug`
1517note: required for `S<X>` to implement `Debug`
1618 --> $DIR/redundant-derive-note-on-unimplemented.rs:9:8
1719 |
tests/ui/errors/trait-bound-error-spans/blame-trait-error.stderr+4-2
......@@ -39,11 +39,13 @@ LL | want(Some(()));
3939 | required by a bound introduced by this call
4040 |
4141 = help: the trait `Iterator` is not implemented for `()`
42help: the trait `T1` is implemented for `Option<It>`
42help: the trait `T1` is conditionally implemented for `Option<It>`
4343 --> $DIR/blame-trait-error.rs:21:1
4444 |
4545LL | impl<It: Iterator> T1 for Option<It> {}
46 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
46 | ^^^^^^^^^--------^^^^^^^^^^^^^^^^^^^
47 | |
48 | unsatisfied requirement introduced here: `(): Iterator`
4749note: required for `Option<()>` to implement `T1`
4850 --> $DIR/blame-trait-error.rs:21:20
4951 |
tests/ui/feature-gates/feature-gate-diagnostic-on-type-error-malformed-args.rs created+9
......@@ -0,0 +1,9 @@
1//@ check-pass
2
3// Regression test for https://github.com/rust-lang/rust/issues/158628.
4
5#[diagnostic::on_type_error(unknown = "")]
6//~^ WARN unknown diagnostic attribute
7pub struct Foo {}
8
9fn main() {}
tests/ui/feature-gates/feature-gate-diagnostic-on-type-error-malformed-args.stderr created+11
......@@ -0,0 +1,11 @@
1warning: unknown diagnostic attribute
2 --> $DIR/feature-gate-diagnostic-on-type-error-malformed-args.rs:5:15
3 |
4LL | #[diagnostic::on_type_error(unknown = "")]
5 | ^^^^^^^^^^^^^
6 |
7 = help: add `#![feature(diagnostic_on_type_error)]` to the crate attributes to enable
8 = note: `#[warn(unknown_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
9
10warning: 1 warning emitted
11
tests/ui/impl-restriction/restriction_resolution_errors.rs+2-2
......@@ -23,7 +23,7 @@ pub mod a {
2323
2424 pub impl(in super::E) trait T6 {} //~ ERROR expected module, found enum `super::E` [E0577]
2525
26 pub impl(in super::super::super) trait T7 {} //~ ERROR too many leading `super` keywords [E0433]
26 pub impl(in super::super::super) trait T7 {} //~ ERROR too many leading `super` keywords within `crate::a::b` [E0433]
2727
2828 // OK paths
2929 pub impl(crate) trait T8 {}
......@@ -53,7 +53,7 @@ pub impl(in crate::a::E) trait T14 {} //~ ERROR expected module, found enum `cra
5353pub impl(crate) trait T15 {}
5454pub impl(self) trait T16 {}
5555
56pub impl(super) trait T17 {} //~ ERROR too many leading `super` keywords [E0433]
56pub impl(super) trait T17 {} //~ ERROR too many leading `super` keywords within `crate` [E0433]
5757
5858pub impl(in external) trait T18 {} //~ ERROR trait implementation can only be restricted to ancestor modules
5959
tests/ui/impl-restriction/restriction_resolution_errors.stderr+4-4
......@@ -16,11 +16,11 @@ error: trait implementation can only be restricted to ancestor modules
1616LL | pub impl(in super::d) trait T4 {}
1717 | ^^^^^^^^
1818
19error[E0433]: too many leading `super` keywords
19error[E0433]: too many leading `super` keywords within `crate::a::b`
2020 --> $DIR/restriction_resolution_errors.rs:26:35
2121 |
2222LL | pub impl(in super::super::super) trait T7 {}
23 | ^^^^^ there are too many leading `super` keywords
23 | ^^^^^ this `super` would go above the crate root
2424
2525error: trait implementation can only be restricted to ancestor modules
2626 --> $DIR/restriction_resolution_errors.rs:36:21
......@@ -40,11 +40,11 @@ error: trait implementation can only be restricted to ancestor modules
4040LL | pub impl(in crate::a) trait T13 {}
4141 | ^^^^^^^^
4242
43error[E0433]: too many leading `super` keywords
43error[E0433]: too many leading `super` keywords within `crate`
4444 --> $DIR/restriction_resolution_errors.rs:56:10
4545 |
4646LL | pub impl(super) trait T17 {}
47 | ^^^^^ there are too many leading `super` keywords
47 | ^^^^^ this `super` would go above the crate root
4848
4949error: trait implementation can only be restricted to ancestor modules
5050 --> $DIR/restriction_resolution_errors.rs:58:13
tests/ui/impl-trait/nested_impl_trait.stderr+8-2
......@@ -50,8 +50,11 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
5050 | |
5151 | the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
5252 |
53help: the trait `Into<U>` is implemented for `T`
53help: the trait `Into<U>` is conditionally implemented for `T`
5454 --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
55 ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL
56 |
57 = note: unsatisfied requirement introduced here: `impl Debug: From<impl Into<u32>>`
5558 = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
5659
5760error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
......@@ -62,8 +65,11 @@ LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
6265 | |
6366 | the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
6467 |
65help: the trait `Into<U>` is implemented for `T`
68help: the trait `Into<U>` is conditionally implemented for `T`
6669 --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
70 ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL
71 |
72 = note: unsatisfied requirement introduced here: `impl Debug: From<impl Into<u32>>`
6773 = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
6874
6975error: aborting due to 7 previous errors
tests/ui/impl-trait/rpit/dyn-in-nested-rpit.rs created+21
......@@ -0,0 +1,21 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/158656>.
2
3//@ revisions: current next
4//@[next] compile-flags: -Znext-solver
5//@ check-pass
6
7trait Trait {}
8
9trait WithAssoc {
10 type Assoc: ?Sized;
11}
12struct Thing;
13impl WithAssoc for Thing {
14 type Assoc = dyn Trait;
15}
16
17fn foo() -> impl WithAssoc<Assoc = impl Trait + ?Sized> {
18 Thing
19}
20
21fn main() {}
tests/ui/keyword/keyword-super-as-identifier.rs+1-1
......@@ -1,3 +1,3 @@
11fn main() {
2 let super = 22; //~ ERROR too many leading `super` keywords
2 let super = 22; //~ ERROR too many leading `super` keywords within `crate`
33}
tests/ui/keyword/keyword-super-as-identifier.stderr+2-2
......@@ -1,8 +1,8 @@
1error[E0433]: too many leading `super` keywords
1error[E0433]: too many leading `super` keywords within `crate`
22 --> $DIR/keyword-super-as-identifier.rs:2:9
33 |
44LL | let super = 22;
5 | ^^^^^ there are too many leading `super` keywords
5 | ^^^^^ this `super` would go above the crate root
66
77error: aborting due to 1 previous error
88
tests/ui/keyword/keyword-super.rs+1-1
......@@ -1,3 +1,3 @@
11fn main() {
2 let super: isize; //~ ERROR: too many leading `super` keywords
2 let super: isize; //~ ERROR: too many leading `super` keywords within `crate`
33}
tests/ui/keyword/keyword-super.stderr+2-2
......@@ -1,8 +1,8 @@
1error[E0433]: too many leading `super` keywords
1error[E0433]: too many leading `super` keywords within `crate`
22 --> $DIR/keyword-super.rs:2:9
33 |
44LL | let super: isize;
5 | ^^^^^ there are too many leading `super` keywords
5 | ^^^^^ this `super` would go above the crate root
66
77error: aborting due to 1 previous error
88
tests/ui/lint/improper-ctypes/nonzero-char.rs created+13
......@@ -0,0 +1,13 @@
1// Regression test for https://github.com/rust-lang/rust/issues/158511.
2
3#![allow(dead_code)]
4#![deny(improper_ctypes)]
5
6use std::num;
7
8extern "C" {
9 fn result_nonzero_u32_t(x: Result<num::NonZero<char>, ()>);
10 //~^ ERROR `extern` block uses type `char`, which is not FFI-safe
11}
12
13fn main() {}
tests/ui/lint/improper-ctypes/nonzero-char.stderr created+16
......@@ -0,0 +1,16 @@
1error: `extern` block uses type `char`, which is not FFI-safe
2 --> $DIR/nonzero-char.rs:9:32
3 |
4LL | fn result_nonzero_u32_t(x: Result<num::NonZero<char>, ()>);
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
6 |
7 = help: consider using `u32` or `libc::wchar_t` instead
8 = note: the `char` type has no C equivalent
9note: the lint level is defined here
10 --> $DIR/nonzero-char.rs:4:9
11 |
12LL | #![deny(improper_ctypes)]
13 | ^^^^^^^^^^^^^^^
14
15error: aborting due to 1 previous error
16
tests/ui/modules/super-at-crate-root.rs+1-1
......@@ -1,6 +1,6 @@
11//! Check that `super` keyword used at the crate root (top-level) results in a compilation error
22//! as there is no parent module to resolve.
33
4use super::f; //~ ERROR too many leading `super` keywords
4use super::f; //~ ERROR too many leading `super` keywords within `crate`
55
66fn main() {}
tests/ui/modules/super-at-crate-root.stderr+2-2
......@@ -1,8 +1,8 @@
1error[E0433]: too many leading `super` keywords
1error[E0433]: too many leading `super` keywords within `crate`
22 --> $DIR/super-at-crate-root.rs:4:5
33 |
44LL | use super::f;
5 | ^^^^^ there are too many leading `super` keywords
5 | ^^^^^ this `super` would go above the crate root
66
77error: aborting due to 1 previous error
88
tests/ui/resolve/impl-items-vis-unresolved.rs+1-1
......@@ -19,7 +19,7 @@ pub struct RawFloatState;
1919impl RawFloatState {
2020 perftools_inline! {
2121 pub(super) fn new() {}
22 //~^ ERROR: too many leading `super` keywords
22 //~^ ERROR: too many leading `super` keywords within `crate`
2323 }
2424}
2525
tests/ui/resolve/impl-items-vis-unresolved.stderr+2-2
......@@ -1,8 +1,8 @@
1error[E0433]: too many leading `super` keywords
1error[E0433]: too many leading `super` keywords within `crate`
22 --> $DIR/impl-items-vis-unresolved.rs:21:13
33 |
44LL | pub(super) fn new() {}
5 | ^^^^^ there are too many leading `super` keywords
5 | ^^^^^ this `super` would go above the crate root
66
77error: aborting due to 1 previous error
88
tests/ui/resolve/issue-117920.rs+1-1
......@@ -1,6 +1,6 @@
11#![crate_type = "lib"]
22
3use super::A; //~ ERROR too many leading `super` keywords
3use super::A; //~ ERROR too many leading `super` keywords within `crate`
44
55mod b {
66 pub trait A {}
tests/ui/resolve/issue-117920.stderr+2-2
......@@ -1,8 +1,8 @@
1error[E0433]: too many leading `super` keywords
1error[E0433]: too many leading `super` keywords within `crate`
22 --> $DIR/issue-117920.rs:3:5
33 |
44LL | use super::A;
5 | ^^^^^ there are too many leading `super` keywords
5 | ^^^^^ this `super` would go above the crate root
66
77error: aborting due to 1 previous error
88
tests/ui/resolve/issue-82156.rs+1-1
......@@ -1,3 +1,3 @@
11fn main() {
2 super(); //~ ERROR: too many leading `super` keywords
2 super(); //~ ERROR: too many leading `super` keywords within `crate`
33}
tests/ui/resolve/issue-82156.stderr+2-2
......@@ -1,8 +1,8 @@
1error[E0433]: too many leading `super` keywords
1error[E0433]: too many leading `super` keywords within `crate`
22 --> $DIR/issue-82156.rs:2:5
33 |
44LL | super();
5 | ^^^^^ there are too many leading `super` keywords
5 | ^^^^^ this `super` would go above the crate root
66
77error: aborting due to 1 previous error
88
tests/ui/resolve/too-many-super-issue-158275.rs created+10
......@@ -0,0 +1,10 @@
1#![crate_type = "lib"]
2
3mod outer {
4 mod inner {
5 struct Example(super::super::super::Impl);
6 //~^ ERROR too many leading `super` keywords within `crate::outer::inner`
7 }
8}
9
10struct Impl;
tests/ui/resolve/too-many-super-issue-158275.stderr created+9
......@@ -0,0 +1,9 @@
1error[E0433]: too many leading `super` keywords within `crate::outer::inner`
2 --> $DIR/too-many-super-issue-158275.rs:5:38
3 |
4LL | struct Example(super::super::super::Impl);
5 | ^^^^^ this `super` would go above the crate root
6
7error: aborting due to 1 previous error
8
9For more information about this error, try `rustc --explain E0433`.
tests/ui/splat/run-splat.rs created+37
......@@ -0,0 +1,37 @@
1//! Check that splat codegen works for simple cases.
2//@ run-pass
3//@ check-run-results
4#![feature(splat, tuple_trait)]
5#![expect(incomplete_features)]
6
7use std::marker::Tuple;
8
9struct Foo;
10
11trait MethodArgs: Tuple {
12 fn call_method(self, this: &Foo);
13}
14
15impl Foo {
16 fn method(&self, #[splat] args: impl MethodArgs) {
17 args.call_method(self)
18 }
19}
20
21impl MethodArgs for (i32, String) {
22 fn call_method(self, _this: &Foo) {
23 dbg!(self.1, self.0);
24 }
25}
26
27impl MethodArgs for (f64,) {
28 fn call_method(self, _this: &Foo) {
29 dbg!(self.0);
30 }
31}
32
33fn main() {
34 let foo = Foo;
35 foo.method(42, "hello splat".to_string());
36 foo.method(3.141);
37}
tests/ui/splat/run-splat.run.stderr created+3
......@@ -0,0 +1,3 @@
1[$DIR/run-splat.rs:23:9] self.1 = "hello splat"
2[$DIR/run-splat.rs:23:9] self.0 = 42
3[$DIR/run-splat.rs:29:9] self.0 = 3.141
tests/ui/splat/splat-dyn-asref-tuple-fail.rs+27-2
......@@ -4,11 +4,36 @@
44#![feature(splat)]
55#![feature(tuple_trait)]
66
7fn dyn_asref_splat<T>(#[splat] _t: &dyn AsRef<T>) where T: std::marker::Tuple {}
8//~^ ERROR cannot use splat attribute
7// Strip binders and their lifetime numbers from error messages
8//@ normalize-stderr: "&.*value: (.*), bound_vars: .*" -> "$1"
9
10// FIXME(splat): Some errors are reported on the callee, but they would be more ergonomic on the
11// caller as well
12fn dyn_asref_splat<T>(#[splat] _t: &dyn AsRef<T>)
13//~^ ERROR cannot use splat attribute; the splatted argument type must be a tuple or unit, not a
14//~| ERROR cannot use splat attribute; the splatted argument type must be a tuple or unit, not a
15//~| ERROR cannot use splat attribute; the splatted argument type must be a tuple or unit, not a
16//~| ERROR cannot use splat attribute; the splatted argument type must be a tuple or unit, not a
17where
18 T: std::marker::Tuple,
19{
20}
921
1022fn main() {
23 // These error patterns are reported on the function definition, but we can't check for two
24 // strings in the same error message
1125 let s: String = "hello".to_owned();
1226 dyn_asref_splat::<String>(&s);
1327 //~^ ERROR `String` is not a tuple
28 //@regex-error-pattern: type must be a tuple or unit, not a .* Trait\(.*AsRef<.*String>\)
29
30 dyn_asref_splat(&s);
31 //@regex-error-pattern: type must be a tuple or unit, not a .* Trait\(.*AsRef<_>\)
32
33 let t = (1u8, 2f32);
34 dyn_asref_splat::<(u8, f32)>(&t);
35 //@regex-error-pattern: type must be a tuple or unit, not a .* Trait\(.*AsRef<\(u8, f32\)>\)
36
37 dyn_asref_splat(&t);
38 //@regex-error-pattern: type must be a tuple or unit, not a .* Trait\(.*AsRef<_>\)
1439}
tests/ui/splat/splat-dyn-asref-tuple-fail.stderr+38-8
......@@ -1,24 +1,54 @@
1error[E0277]: cannot use splat attribute; the splatted argument type must be a tuple or unit, not a &'?3 dyn [Binder { value: Trait(std::convert::AsRef<std::string::String>), bound_vars: [] }] + '?3 (&'?3 dyn [Binder { value: Trait(std::convert::AsRef<std::string::String>), bound_vars: [] }] + '?3)
2 --> $DIR/splat-dyn-asref-tuple-fail.rs:7:36
1error[E0277]: cannot use splat attribute; the splatted argument type must be a tuple or unit, not a Trait(std::convert::AsRef<std::string::String>)
2 --> $DIR/splat-dyn-asref-tuple-fail.rs:12:36
33 |
4LL | fn dyn_asref_splat<T>(#[splat] _t: &dyn AsRef<T>) where T: std::marker::Tuple {}
4LL | fn dyn_asref_splat<T>(#[splat] _t: &dyn AsRef<T>)
55 | ^^^^^^^^^^^^^
66...
77LL | dyn_asref_splat::<String>(&s);
88 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
99
1010error[E0277]: `String` is not a tuple
11 --> $DIR/splat-dyn-asref-tuple-fail.rs:12:23
11 --> $DIR/splat-dyn-asref-tuple-fail.rs:26:23
1212 |
1313LL | dyn_asref_splat::<String>(&s);
1414 | ^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `String`
1515 |
1616note: required by a bound in `dyn_asref_splat`
17 --> $DIR/splat-dyn-asref-tuple-fail.rs:7:60
17 --> $DIR/splat-dyn-asref-tuple-fail.rs:18:8
1818 |
19LL | fn dyn_asref_splat<T>(#[splat] _t: &dyn AsRef<T>) where T: std::marker::Tuple {}
20 | ^^^^^^^^^^^^^^^^^^ required by this bound in `dyn_asref_splat`
19LL | fn dyn_asref_splat<T>(#[splat] _t: &dyn AsRef<T>)
20 | --------------- required by a bound in this function
21...
22LL | T: std::marker::Tuple,
23 | ^^^^^^^^^^^^^^^^^^ required by this bound in `dyn_asref_splat`
24
25error[E0277]: cannot use splat attribute; the splatted argument type must be a tuple or unit, not a Trait(std::convert::AsRef<_>)
26 --> $DIR/splat-dyn-asref-tuple-fail.rs:12:36
27 |
28LL | fn dyn_asref_splat<T>(#[splat] _t: &dyn AsRef<T>)
29 | ^^^^^^^^^^^^^
30...
31LL | dyn_asref_splat(&s);
32 | ^^^^^^^^^^^^^^^^^^^
33
34error[E0277]: cannot use splat attribute; the splatted argument type must be a tuple or unit, not a Trait(std::convert::AsRef<(u8, f32)>)
35 --> $DIR/splat-dyn-asref-tuple-fail.rs:12:36
36 |
37LL | fn dyn_asref_splat<T>(#[splat] _t: &dyn AsRef<T>)
38 | ^^^^^^^^^^^^^
39...
40LL | dyn_asref_splat::<(u8, f32)>(&t);
41 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42
43error[E0277]: cannot use splat attribute; the splatted argument type must be a tuple or unit, not a Trait(std::convert::AsRef<_>)
44 --> $DIR/splat-dyn-asref-tuple-fail.rs:12:36
45 |
46LL | fn dyn_asref_splat<T>(#[splat] _t: &dyn AsRef<T>)
47 | ^^^^^^^^^^^^^
48...
49LL | dyn_asref_splat(&t);
50 | ^^^^^^^^^^^^^^^^^^^
2151
22error: aborting due to 2 previous errors
52error: aborting due to 5 previous errors
2353
2454For more information about this error, try `rustc --explain E0277`.
tests/ui/splat/splat-fn-ptr-cast-fail.rs created+25
......@@ -0,0 +1,25 @@
1//! Test casting splatted functions to non-splatted function pointers fails.
2
3#![allow(incomplete_features)]
4#![feature(splat, tuple_trait)]
5
6use std::marker::Tuple;
7
8fn tuple_args(#[splat] (_a, _b): (u32, i8)) {}
9
10fn splat_non_terminal_arg(#[splat] (_a, _b): (u32, i8), _c: f64) {}
11
12fn f<Args: Tuple>(#[splat] args: Args) {}
13
14fn main() {
15 // Function pointers
16 let _fn_ptr: fn((u32, i8)) = tuple_args; //~ ERROR mismatched types
17 let _fn_ptr: fn((u32, i8), f64) = splat_non_terminal_arg; //~ ERROR mismatched types
18
19 let _fn_ptr: fn((u32, i8)) = tuple_args as fn((u32, i8)); //~ ERROR non-primitive cast
20 let _fn_ptr: fn((u32, i8), f64) = splat_non_terminal_arg as fn((u32, i8), f64); //~ ERROR non-primitive cast
21
22 // Bug #158603 regression test variants
23 const _F2: fn((u8, u32)) = f::<(u8, u32)>; //~ ERROR mismatched types
24 const _F1: fn(((u8, u32),)) = f::<((u8, u32),)>; //~ ERROR mismatched types
25}
tests/ui/splat/splat-fn-ptr-cast-fail.stderr created+60
......@@ -0,0 +1,60 @@
1error[E0308]: mismatched types
2 --> $DIR/splat-fn-ptr-cast-fail.rs:16:34
3 |
4LL | let _fn_ptr: fn((u32, i8)) = tuple_args;
5 | ------------- ^^^^^^^^^^ expected fn with no splatted arg, found fn with arg 0 splatted
6 | |
7 | expected due to this
8 |
9 = note: expected fn pointer `fn((_, _))`
10 found fn item `fn(#[splat] (_, _)) {tuple_args}`
11
12error[E0308]: mismatched types
13 --> $DIR/splat-fn-ptr-cast-fail.rs:17:39
14 |
15LL | let _fn_ptr: fn((u32, i8), f64) = splat_non_terminal_arg;
16 | ------------------ ^^^^^^^^^^^^^^^^^^^^^^ expected fn with no splatted arg, found fn with arg 0 splatted
17 | |
18 | expected due to this
19 |
20 = note: expected fn pointer `fn((_, _), _)`
21 found fn item `fn(#[splat] (_, _), _) {splat_non_terminal_arg}`
22
23error[E0605]: non-primitive cast: `fn(, #[splat](u32, i8)) {tuple_args}` as `fn((u32, i8))`
24 --> $DIR/splat-fn-ptr-cast-fail.rs:19:34
25 |
26LL | let _fn_ptr: fn((u32, i8)) = tuple_args as fn((u32, i8));
27 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
28
29error[E0605]: non-primitive cast: `fn(, #[splat](u32, i8), f64) {splat_non_terminal_arg}` as `fn((u32, i8), f64)`
30 --> $DIR/splat-fn-ptr-cast-fail.rs:20:39
31 |
32LL | let _fn_ptr: fn((u32, i8), f64) = splat_non_terminal_arg as fn((u32, i8), f64);
33 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
34
35error[E0308]: mismatched types
36 --> $DIR/splat-fn-ptr-cast-fail.rs:23:32
37 |
38LL | const _F2: fn((u8, u32)) = f::<(u8, u32)>;
39 | ------------- ^^^^^^^^^^^^^^ expected fn with no splatted arg, found fn with arg 0 splatted
40 | |
41 | expected because of the type of the constant
42 |
43 = note: expected fn pointer `fn((_, _))`
44 found fn item `fn(#[splat] (_, _)) {f::<(u8, u32)>}`
45
46error[E0308]: mismatched types
47 --> $DIR/splat-fn-ptr-cast-fail.rs:24:35
48 |
49LL | const _F1: fn(((u8, u32),)) = f::<((u8, u32),)>;
50 | ---------------- ^^^^^^^^^^^^^^^^^ expected fn with no splatted arg, found fn with arg 0 splatted
51 | |
52 | expected because of the type of the constant
53 |
54 = note: expected fn pointer `fn(((_, _),))`
55 found fn item `fn(#[splat] ((_, _),)) {f::<((u8, u32),)>}`
56
57error: aborting due to 6 previous errors
58
59Some errors have detailed explanations: E0308, E0605.
60For more information about an error, try `rustc --explain E0308`.
tests/ui/splat/splat-fn-tuple-generic-fail.rs+7-1
......@@ -4,7 +4,11 @@
44#![feature(splat)]
55#![feature(tuple_trait)]
66
7fn splat_generic_tuple<T: std::marker::Tuple>(#[splat] _t: T) {}
7use std::marker::Tuple;
8
9fn splat_generic_tuple<T: Tuple>(#[splat] _t: T) {}
10
11fn f<Args: Tuple>(#[splat] args: Args) {}
812
913fn main() {
1014 // FIXME(splat): should splatted functions be callable with tupled and un-tupled arguments?
......@@ -24,4 +28,6 @@ fn main() {
2428
2529 splat_generic_tuple::<(u32, i8)>((1, 2)); //~ ERROR this splatted function takes 2 arguments, but 1 was provided
2630 splat_generic_tuple::<(u32, i8)>((1u32, 2i8)); //~ ERROR this splatted function takes 2 arguments, but 1 was provided
31
32 const F1: fn((u8, u32)) = f::<(u8, u32)>; //~ ERROR mismatched types
2733}
tests/ui/splat/splat-fn-tuple-generic-fail.stderr+20-8
......@@ -1,39 +1,51 @@
11error[E0057]: this splatted function takes 2 arguments, but 1 was provided
2 --> $DIR/splat-fn-tuple-generic-fail.rs:19:5
2 --> $DIR/splat-fn-tuple-generic-fail.rs:23:5
33 |
44LL | splat_generic_tuple::<(((u32, i8)))>((1, 2));
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
77error[E0057]: this splatted function takes 2 arguments, but 1 was provided
8 --> $DIR/splat-fn-tuple-generic-fail.rs:20:5
8 --> $DIR/splat-fn-tuple-generic-fail.rs:24:5
99 |
1010LL | splat_generic_tuple::<(((u32, i8)))>((1u32, 2i8));
1111 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212
1313error[E0057]: this splatted function takes 2 arguments, but 1 was provided
14 --> $DIR/splat-fn-tuple-generic-fail.rs:22:5
14 --> $DIR/splat-fn-tuple-generic-fail.rs:26:5
1515 |
1616LL | splat_generic_tuple::<((u32, i8))>((1, 2));
1717 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818
1919error[E0057]: this splatted function takes 2 arguments, but 1 was provided
20 --> $DIR/splat-fn-tuple-generic-fail.rs:23:5
20 --> $DIR/splat-fn-tuple-generic-fail.rs:27:5
2121 |
2222LL | splat_generic_tuple::<((u32, i8))>((1u32, 2i8));
2323 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2424
2525error[E0057]: this splatted function takes 2 arguments, but 1 was provided
26 --> $DIR/splat-fn-tuple-generic-fail.rs:25:5
26 --> $DIR/splat-fn-tuple-generic-fail.rs:29:5
2727 |
2828LL | splat_generic_tuple::<(u32, i8)>((1, 2));
2929 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3030
3131error[E0057]: this splatted function takes 2 arguments, but 1 was provided
32 --> $DIR/splat-fn-tuple-generic-fail.rs:26:5
32 --> $DIR/splat-fn-tuple-generic-fail.rs:30:5
3333 |
3434LL | splat_generic_tuple::<(u32, i8)>((1u32, 2i8));
3535 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3636
37error: aborting due to 6 previous errors
37error[E0308]: mismatched types
38 --> $DIR/splat-fn-tuple-generic-fail.rs:32:31
39 |
40LL | const F1: fn((u8, u32)) = f::<(u8, u32)>;
41 | ------------- ^^^^^^^^^^^^^^ expected fn with no splatted arg, found fn with arg 0 splatted
42 | |
43 | expected because of the type of the constant
44 |
45 = note: expected fn pointer `fn((_, _))`
46 found fn item `fn(#[splat] (_, _)) {f::<(u8, u32)>}`
47
48error: aborting due to 7 previous errors
3849
39For more information about this error, try `rustc --explain E0057`.
50Some errors have detailed explanations: E0057, E0308.
51For more information about an error, try `rustc --explain E0057`.
tests/ui/splat/splat-generics-everywhere.rs+20-7
......@@ -3,11 +3,10 @@
33
44#![allow(incomplete_features)]
55#![feature(splat)]
6#![feature(tuple_trait)]
67
78struct Foo<T>(T);
89
9// FIXME(splat): also add assoc/method with splatted generic tuple traits
10// also add generics inside the splatted tuple
1110impl<T> Foo<T> {
1211 fn new(t: T) -> Self {
1312 Self(t)
......@@ -20,12 +19,13 @@ impl<T> Foo<T> {
2019 fn lifetime<'a>(&self, #[splat] _s: (u32, f64, &'a str)) {}
2120
2221 fn const_generic<const N: usize>(&self, #[splat] _s: (u32, f64, [u8; N])) {}
22
23 fn generic_in_tuple<U>(&self, #[splat] _s: (U, u32)) {}
24
25 fn generic_tuple_assoc<U: std::marker::Tuple>(_u: U, #[splat] _s: ()) {}
2326}
2427
25// FIXME(splat): also add generics to the trait
26// also add assoc/method with splatted generic tuple traits
27// also add generics inside the splatted tuple
28trait BarTrait {
28trait BarTrait<T> {
2929 fn trait_assoc<W>(w: W, #[splat] _s: ());
3030
3131 fn trait_method<X>(&self, x: X, #[splat] _s: (u32, f64));
......@@ -33,9 +33,13 @@ trait BarTrait {
3333 fn trait_lifetime<'a>(&self, #[splat] _s: (u32, f64, &'a str)) {}
3434
3535 fn trait_const_generic<const N: usize>(&self, #[splat] _s: (u32, f64, [u8; N])) {}
36
37 fn trait_generic_in_tuple<U>(&self, #[splat] _s: (T, U)) {}
38
39 fn trait_generic_tuple<U: std::marker::Tuple>(&self, #[splat] _s: U) {}
3640}
3741
38impl<T> BarTrait for Foo<T> {
42impl<T> BarTrait<T> for Foo<T> {
3943 fn trait_assoc<W>(_w: W, #[splat] _s: ()) {}
4044
4145 fn trait_method<X>(&self, _x: X, #[splat] _s: (u32, f64)) {}
......@@ -43,6 +47,10 @@ impl<T> BarTrait for Foo<T> {
4347 fn trait_lifetime<'a>(&self, #[splat] _s: (u32, f64, &'a str)) {}
4448
4549 fn trait_const_generic<const N: usize>(&self, #[splat] _s: (u32, f64, [u8; N])) {}
50
51 fn trait_generic_in_tuple<U>(&self, #[splat] _s: (T, U)) {}
52
53 fn trait_generic_tuple<U: std::marker::Tuple>(&self, #[splat] _s: U) {}
4654}
4755
4856fn main() {
......@@ -57,8 +65,13 @@ fn main() {
5765 foo.method("v", 1u32, 2.3);
5866 foo.lifetime(1u32, 2.3, "asdf");
5967 foo.const_generic(1u32, 2.3, [1, 2, 3]);
68 foo.generic_in_tuple(42i32, 1u32);
69 Foo::<f32>::generic_tuple_assoc(());
6070
71 Foo::<u32>::trait_assoc("w");
6172 foo.trait_method("x", 42u32, 9.8);
6273 foo.trait_lifetime(1u32, 2.3, "asdf");
6374 foo.trait_const_generic(1u32, 2.3, [1, 2, 3]);
75 foo.trait_generic_in_tuple("hello", 42i32);
76 foo.trait_generic_tuple();
6477}
tests/ui/splat/splat-self.rs created+21
......@@ -0,0 +1,21 @@
1//@ run-pass
2//@ check-run-results
3//! Test using `#[splat]` on self arguments of trait methods.
4
5#![feature(splat)]
6#![expect(incomplete_features)]
7
8trait Trait {
9 fn method(#[splat] self: Self);
10}
11
12impl Trait for (i32, i64) {
13 fn method(#[splat] self: Self) {
14 println!("{self:?}");
15 }
16}
17
18fn main() {
19 (1_i32, 2_i64).method();
20 Trait::method(3_i32, 4_i64);
21}
tests/ui/splat/splat-self.run.stdout created+2
......@@ -0,0 +1,2 @@
1(1, 2)
2(3, 4)
tests/ui/traits/copy-bounds-impl-type-params.stderr+8-4
......@@ -80,11 +80,13 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
8080LL | let a = t as Box<dyn Gettable<String>>;
8181 | ^ the trait `Copy` is not implemented for `String`
8282 |
83help: the trait `Gettable<T>` is implemented for `S<T>`
83help: the trait `Gettable<T>` is conditionally implemented for `S<T>`
8484 --> $DIR/copy-bounds-impl-type-params.rs:14:1
8585 |
8686LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
87 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
87 | ^^^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
88 | |
89 | unsatisfied requirement introduced here: `String: Copy`
8890note: required for `S<String>` to implement `Gettable<String>`
8991 --> $DIR/copy-bounds-impl-type-params.rs:14:32
9092 |
......@@ -100,11 +102,13 @@ error[E0277]: the trait bound `Foo: Copy` is not satisfied
100102LL | let a: Box<dyn Gettable<Foo>> = t;
101103 | ^ the trait `Copy` is not implemented for `Foo`
102104 |
103help: the trait `Gettable<T>` is implemented for `S<T>`
105help: the trait `Gettable<T>` is conditionally implemented for `S<T>`
104106 --> $DIR/copy-bounds-impl-type-params.rs:14:1
105107 |
106108LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
107 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
109 | ^^^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
110 | |
111 | unsatisfied requirement introduced here: `Foo: Copy`
108112note: required for `S<Foo>` to implement `Gettable<Foo>`
109113 --> $DIR/copy-bounds-impl-type-params.rs:14:32
110114 |
tests/ui/traits/error_reporting/conditionally-implemented-trait-158423.rs created+28
......@@ -0,0 +1,28 @@
1struct Test(i32, i64);
2trait Foo<'a> {
3 type Assoc;
4}
5
6trait SimpleFoo {
7 type SimpleAssoc;
8}
9impl<'a, T> Foo<'a> for T where T: SimpleFoo {
10 type Assoc = T::SimpleAssoc;
11}
12
13impl SimpleFoo for i32 {
14 type SimpleAssoc = i32;
15}
16impl SimpleFoo for i64 {
17 type SimpleAssoc = i32;
18}
19
20impl<'a> Foo<'a> for Test where i32: Foo<'a, Assoc = i32>, i64: Foo<'a, Assoc = i64> {
21 type Assoc = Test;
22}
23
24fn process<'a, T: Foo<'a>>(_input: T) {}
25fn test() { process(Test(0, 1)) }
26//~^ ERROR the trait bound `Test: Foo<'_>` is not satisfied
27
28fn main() {}
tests/ui/traits/error_reporting/conditionally-implemented-trait-158423.stderr created+29
......@@ -0,0 +1,29 @@
1error[E0277]: the trait bound `Test: Foo<'_>` is not satisfied
2 --> $DIR/conditionally-implemented-trait-158423.rs:25:21
3 |
4LL | fn test() { process(Test(0, 1)) }
5 | ------- ^^^^^^^^^^ unsatisfied trait bound
6 | |
7 | required by a bound introduced by this call
8 |
9help: the trait `Foo<'_>` is not implemented for `Test`
10 --> $DIR/conditionally-implemented-trait-158423.rs:1:1
11 |
12LL | struct Test(i32, i64);
13 | ^^^^^^^^^^^
14help: the trait `Foo<'_>` is conditionally implemented for `Test`
15 --> $DIR/conditionally-implemented-trait-158423.rs:20:1
16 |
17LL | impl<'a> Foo<'a> for Test where i32: Foo<'a, Assoc = i32>, i64: Foo<'a, Assoc = i64> {
18 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^
19 | |
20 | unsatisfied requirement introduced here: `<i64 as Foo<'_>>::Assoc == i64`
21note: required by a bound in `process`
22 --> $DIR/conditionally-implemented-trait-158423.rs:24:19
23 |
24LL | fn process<'a, T: Foo<'a>>(_input: T) {}
25 | ^^^^^^^ required by this bound in `process`
26
27error: aborting due to 1 previous error
28
29For more information about this error, try `rustc --explain E0277`.
tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr+1-1
......@@ -7,7 +7,7 @@ LL | struct LocalTy;
77LL | impl Trait for <LocalTy as Overflow>::Assoc {}
88 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
99 |
10 = note: overflow evaluating the requirement `_ == <LocalTy as Overflow>::Assoc`
10 = note: overflow evaluating the requirement `<LocalTy as Overflow>::Assoc == _`
1111 = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`)
1212
1313error: aborting due to 1 previous error
tests/ui/traits/next-solver/consider_builtin_pointee_candidate-instantiate-result-fail.rs created+15
......@@ -0,0 +1,15 @@
1//@ compile-flags: -Znext-solver
2
3//! This test is extremely similar to `nested-rerun-not-erased-in-normalizes-to.rs`, however,
4//! instead of the eager normalization failing due to an anon const when in ErasedNotCoherence, this
5//! just straight up fails normalization because u32 is not Iterator
6
7#![feature(ptr_metadata)]
8
9struct ThisStructAintValid(<u32 as Iterator>::Item);
10//~^ ERROR `u32` is not an iterator
11
12fn main() {
13 let y: <ThisStructAintValid as std::ptr::Pointee>::Metadata;
14 //~^ ERROR type mismatch resolving `<ThisStructAintValid as Pointee>::Metadata == _`
15}
tests/ui/traits/next-solver/consider_builtin_pointee_candidate-instantiate-result-fail.stderr created+18
......@@ -0,0 +1,18 @@
1error[E0277]: `u32` is not an iterator
2 --> $DIR/consider_builtin_pointee_candidate-instantiate-result-fail.rs:9:28
3 |
4LL | struct ThisStructAintValid(<u32 as Iterator>::Item);
5 | ^^^^^^^^^^^^^^^^^^^^^^^ `u32` is not an iterator
6 |
7 = help: the trait `Iterator` is not implemented for `u32`
8
9error[E0271]: type mismatch resolving `<ThisStructAintValid as Pointee>::Metadata == _`
10 --> $DIR/consider_builtin_pointee_candidate-instantiate-result-fail.rs:13:12
11 |
12LL | let y: <ThisStructAintValid as std::ptr::Pointee>::Metadata;
13 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
14
15error: aborting due to 2 previous errors
16
17Some errors have detailed explanations: E0271, E0277.
18For more information about an error, try `rustc --explain E0271`.
tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr+2-1
......@@ -9,13 +9,14 @@ help: the trait `Trait<_, _, _>` is not implemented for `A<X>`
99 |
1010LL | struct A<T>(*const T);
1111 | ^^^^^^^^^^^
12help: the trait `Trait<U, V, D>` is implemented for `A<T>`
12help: the trait `Trait<U, V, D>` is conditionally implemented for `A<T>`
1313 --> $DIR/incompleteness-unstable-result.rs:34:1
1414 |
1515LL | / impl<T, U, V, D> Trait<U, V, D> for A<T>
1616LL | | where
1717LL | | T: IncompleteGuidance<U, V>,
1818LL | | A<T>: Trait<U, D, V>,
19 | | -------------- unsatisfied requirement introduced here: `A<_>: Trait<_, _, _>`
1920LL | | B<T>: Trait<U, V, D>,
2021LL | | (): ToU8<D>,
2122 | |________________^
tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr+2-1
......@@ -9,13 +9,14 @@ help: the trait `Trait<_, _, _>` is not implemented for `A<X>`
99 |
1010LL | struct A<T>(*const T);
1111 | ^^^^^^^^^^^
12help: the trait `Trait<U, V, D>` is implemented for `A<T>`
12help: the trait `Trait<U, V, D>` is conditionally implemented for `A<T>`
1313 --> $DIR/incompleteness-unstable-result.rs:34:1
1414 |
1515LL | / impl<T, U, V, D> Trait<U, V, D> for A<T>
1616LL | | where
1717LL | | T: IncompleteGuidance<U, V>,
1818LL | | A<T>: Trait<U, D, V>,
19 | | -------------- unsatisfied requirement introduced here: `A<_>: Trait<_, _, _>`
1920LL | | B<T>: Trait<U, V, D>,
2021LL | | (): ToU8<D>,
2122 | |________________^
tests/ui/traits/next-solver/nested-rerun-not-erased-in-normalizes-to.rs created+28
......@@ -0,0 +1,28 @@
1//@ build-pass
2//@ compile-flags: -Znext-solver
3
4//! Consider:
5//!
6//! goal is <StructTailHasAnonConst as Pointee>::Metadata == ?0, in a typing context of
7//! ErasedNotCoherence
8//!
9//! `consider_builtin_pointee_candidate` looks at StructTailHasAnonConst, realizes it's an ADT,
10//! fetches the struct tail (which is `S<{ 2 + 2 }>`), and calls `instantiate_normalizes_to_term`
11//! with the result of `<Struct<{ 2 + 2 }> as Pointee>::Metadata`
12//!
13//! `instantiate_normalizes_to_term` `.eq()`s `<Struct<{ 2 + 2 }> as Pointee>::Metadata` and `?0`
14//!
15//! this eagerly normalizes, which normalizes the anon const, which fails due to ErasedNotCoherence
16//!
17//! this causes the `.eq()` in `instantiate_normalizes_to_term` to fail, which used to have an
18//! unwrap, which ICEd
19
20#![feature(ptr_metadata)]
21
22struct S<const N: usize>;
23
24struct StructTailHasAnonConst(S<{ 2 + 2 }>);
25
26fn main() {
27 let y: <StructTailHasAnonConst as std::ptr::Pointee>::Metadata;
28}
tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs+1
......@@ -14,6 +14,7 @@ fn needs_bar<S: Bar>() {}
1414fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() {
1515 needs_bar::<T::Assoc1>();
1616 //~^ ERROR: the trait bound `<T as Foo2>::Assoc2: Bar` is not satisfied
17 //~| ERROR: the size for values of type `<T as Foo2>::Assoc2` cannot be known at compilation time
1718}
1819
1920fn main() {}
tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr+22-1
......@@ -14,6 +14,27 @@ help: consider further restricting the associated type
1414LL | fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() where <T as Foo2>::Assoc2: Bar {
1515 | ++++++++++++++++++++++++++++++
1616
17error: aborting due to 1 previous error
17error[E0277]: the size for values of type `<T as Foo2>::Assoc2` cannot be known at compilation time
18 --> $DIR/recursive-self-normalization-2.rs:15:17
19 |
20LL | needs_bar::<T::Assoc1>();
21 | ^^^^^^^^^ doesn't have a size known at compile-time
22 |
23 = help: the trait `Sized` is not implemented for `<T as Foo2>::Assoc2`
24note: required by an implicit `Sized` bound in `needs_bar`
25 --> $DIR/recursive-self-normalization-2.rs:12:14
26 |
27LL | fn needs_bar<S: Bar>() {}
28 | ^ required by the implicit `Sized` requirement on this type parameter in `needs_bar`
29help: consider further restricting the associated type
30 |
31LL | fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() where <T as Foo2>::Assoc2: Sized {
32 | ++++++++++++++++++++++++++++++++
33help: consider relaxing the implicit `Sized` restriction
34 |
35LL | fn needs_bar<S: Bar + ?Sized>() {}
36 | ++++++++
37
38error: aborting due to 2 previous errors
1839
1940For more information about this error, try `rustc --explain E0277`.