@@ -717,16 +717,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
717717 trait_ref : & hir:: TraitRef < ' tcx > ,
718718 self_ty : Ty < ' tcx > ,
719719 ) -> ty:: TraitRef < ' tcx > {
720- let _ = self . prohibit_generic_args (
721- trait_ref. path . segments . split_last ( ) . unwrap ( ) . 1 . iter ( ) ,
722- GenericsArgsErrExtend :: None ,
723- ) ;
720+ let [ leading_segments @ .., segment] = trait_ref. path . segments else { bug ! ( ) } ;
721+
722+ let _ = self . prohibit_generic_args ( leading_segments. iter ( ) , GenericsArgsErrExtend :: None ) ;
724723
725724 self . lower_mono_trait_ref (
726725 trait_ref. path . span ,
727726 trait_ref. trait_def_id ( ) . unwrap_or_else ( || FatalError . raise ( ) ) ,
728727 self_ty,
729- trait_ref . path . segments . last ( ) . unwrap ( ) ,
728+ segment ,
730729 true ,
731730 )
732731 }
@@ -757,7 +756,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
757756 #[ instrument( level = "debug" , skip( self , bounds) ) ]
758757 pub ( crate ) fn lower_poly_trait_ref (
759758 & self ,
760- poly_trait_ref : & hir:: PolyTraitRef < ' tcx > ,
759+ & hir:: PolyTraitRef {
760+ bound_generic_params,
761+ modifiers : hir:: TraitBoundModifiers { constness, polarity } ,
762+ trait_ref,
763+ span,
764+ } : & hir:: PolyTraitRef < ' tcx > ,
761765 self_ty : Ty < ' tcx > ,
762766 bounds : & mut Vec < ( ty:: Clause < ' tcx > , Span ) > ,
763767 predicate_filter : PredicateFilter ,
@@ -767,52 +771,66 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
767771
768772 // We use the *resolved* bound vars later instead of the HIR ones since the former
769773 // also include the bound vars of the overarching predicate if applicable.
770- let hir:: PolyTraitRef { bound_generic_params : _, modifiers, trait_ref, span } =
771- * poly_trait_ref;
772- let hir:: TraitBoundModifiers { constness, polarity } = modifiers;
774+ let _ = bound_generic_params;
773775
774776 let trait_def_id = trait_ref. trait_def_id ( ) . unwrap_or_else ( || FatalError . raise ( ) ) ;
775777
776778 // Relaxed bounds `?Trait` and `PointeeSized` bounds aren't represented in the `middle::ty` IR
777779 // as they denote the *absence* of a default bound. However, we can't bail out early here since
778780 // we still need to perform several validation steps (see below). Instead, simply "pour" all
779781 // resulting bounds "down the drain", i.e., into a new `Vec` that just gets dropped at the end.
780- let ( polarity, bounds) = match polarity {
781- rustc_ast:: BoundPolarity :: Positive
782- if tcx. is_lang_item ( trait_def_id, hir:: LangItem :: PointeeSized ) =>
783- {
782+ let transient = match polarity {
783+ hir:: BoundPolarity :: Positive => {
784784 // To elaborate on the comment directly above, regarding `PointeeSized` specifically,
785785 // we don't "reify" such bounds to avoid trait system limitations -- namely,
786786 // non-global where-clauses being preferred over item bounds (where `PointeeSized`
787787 // bounds would be proven) -- which can result in errors when a `PointeeSized`
788788 // supertrait / bound / predicate is added to some items.
789- ( ty :: PredicatePolarity :: Positive , & mut Vec :: new ( ) )
789+ tcx . is_lang_item ( trait_def_id , hir :: LangItem :: PointeeSized )
790790 }
791- rustc_ast:: BoundPolarity :: Positive => ( ty:: PredicatePolarity :: Positive , bounds) ,
792- rustc_ast:: BoundPolarity :: Negative ( _) => ( ty:: PredicatePolarity :: Negative , bounds) ,
793- rustc_ast:: BoundPolarity :: Maybe ( _) => {
791+ hir:: BoundPolarity :: Negative ( _) => false ,
792+ hir:: BoundPolarity :: Maybe ( _) => {
794793 self . require_bound_to_relax_default_trait ( trait_ref, span) ;
794+ true
795+ }
796+ } ;
795797
796- ( ty:: PredicatePolarity :: Positive , & mut Vec :: new ( ) )
798+ let polarity = match polarity {
799+ hir:: BoundPolarity :: Positive | hir:: BoundPolarity :: Maybe ( _) => {
800+ ty:: PredicatePolarity :: Positive
797801 }
802+ hir:: BoundPolarity :: Negative ( _) => ty:: PredicatePolarity :: Negative ,
798803 } ;
799804
800- let trait_segment = trait_ref. path . segments . last ( ) . unwrap ( ) ;
805+ let [ leading_segments @ .. , segment ] = trait_ref. path . segments else { bug ! ( ) } ;
801806
802- let _ = self . prohibit_generic_args (
803- trait_ref. path . segments . split_last ( ) . unwrap ( ) . 1 . iter ( ) ,
804- GenericsArgsErrExtend :: None ,
805- ) ;
806- self . report_internal_fn_trait ( span, trait_def_id, trait_segment, false ) ;
807+ let _ = self . prohibit_generic_args ( leading_segments. iter ( ) , GenericsArgsErrExtend :: None ) ;
808+ self . report_internal_fn_trait ( span, trait_def_id, segment, false ) ;
807809
808810 let ( generic_args, arg_count) = self . lower_generic_args_of_path (
809811 trait_ref. path . span ,
810812 trait_def_id,
811813 & [ ] ,
812- trait_segment ,
814+ segment ,
813815 Some ( self_ty) ,
814816 ) ;
815817
818+ let constraints = segment. args ( ) . constraints ;
819+
820+ if transient && ( !generic_args. is_empty ( ) || !constraints. is_empty ( ) ) {
821+ // Since the bound won't be present in the `middle::ty` IR for the reasons established
822+ // above, any arguments or constraints won't be checked for well-formedness later.
823+ //
824+ // To be clear, this is only an issue if the trait ref is valid according to this
825+ // function which can only happen if the corresponding default trait has generic
826+ // parameters or associated items which would be degenerate.
827+ //
828+ // This guards us against such situations. Example: `?Bound<'a, Vec<str>, { panic!() }>`
829+ // where `/* default */ trait Bound<'a: 'static, T, const N: usize> {}`.
830+ self . dcx ( )
831+ . span_delayed_bug ( span, "transient bound should not have args or constraints" ) ;
832+ }
833+
816834 let bound_vars = tcx. late_bound_vars ( trait_ref. hir_ref_id ) ;
817835 debug ! ( ?bound_vars) ;
818836
@@ -924,7 +942,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
924942 == OverlappingAsssocItemConstraints :: Forbidden )
925943 . then_some ( FxIndexMap :: default ( ) ) ;
926944
927- for constraint in trait_segment . args ( ) . constraints {
945+ for constraint in constraints {
928946 // Don't register any associated item constraints for negative bounds,
929947 // since we should have emitted an error for them earlier, and they
930948 // would not be well-formed!
@@ -1916,10 +1934,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19161934 Res :: Def ( DefKind :: OpaqueTy , did) => {
19171935 // Check for desugared `impl Trait`.
19181936 assert_matches ! ( tcx. opaque_ty_origin( did) , hir:: OpaqueTyOrigin :: TyAlias { .. } ) ;
1919- let item_segment = path. segments . split_last ( ) . unwrap ( ) ;
1920- let _ = self
1921- . prohibit_generic_args ( item_segment. 1 . iter ( ) , GenericsArgsErrExtend :: OpaqueTy ) ;
1922- let args = self . lower_generic_args_of_path_segment ( span, did, item_segment. 0 ) ;
1937+ let [ leading_segments @ .., segment] = path. segments else { bug ! ( ) } ;
1938+ let _ = self . prohibit_generic_args (
1939+ leading_segments. iter ( ) ,
1940+ GenericsArgsErrExtend :: OpaqueTy ,
1941+ ) ;
1942+ let args = self . lower_generic_args_of_path_segment ( span, did, segment) ;
19231943 Ty :: new_opaque ( tcx, did, args)
19241944 }
19251945 Res :: Def (
@@ -1931,11 +1951,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19311951 did,
19321952 ) => {
19331953 assert_eq ! ( opt_self_ty, None ) ;
1934- let _ = self . prohibit_generic_args (
1935- path. segments . split_last ( ) . unwrap ( ) . 1 . iter ( ) ,
1936- GenericsArgsErrExtend :: None ,
1937- ) ;
1938- self . lower_path_segment ( span, did, path. segments . last ( ) . unwrap ( ) )
1954+ let [ leading_segments @ .., segment] = path. segments else { bug ! ( ) } ;
1955+ let _ = self
1956+ . prohibit_generic_args ( leading_segments. iter ( ) , GenericsArgsErrExtend :: None ) ;
1957+ self . lower_path_segment ( span, did, segment)
19391958 }
19401959 Res :: Def ( kind @ DefKind :: Variant , def_id)
19411960 if let PermitVariants :: Yes = permit_variants =>
@@ -1955,8 +1974,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19551974 GenericsArgsErrExtend :: DefVariant ( & path. segments ) ,
19561975 ) ;
19571976
1958- let GenericPathSegment ( def_id, index) = generic_segments. last ( ) . unwrap ( ) ;
1959- self . lower_path_segment ( span, * def_id, & path. segments [ * index] )
1977+ let & GenericPathSegment ( def_id, index) = generic_segments. last ( ) . unwrap ( ) ;
1978+ self . lower_path_segment ( span, def_id, & path. segments [ index] )
19601979 }
19611980 Res :: Def ( DefKind :: TyParam , def_id) => {
19621981 assert_eq ! ( opt_self_ty, None ) ;
@@ -2242,15 +2261,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22422261 }
22432262 Res :: Def ( DefKind :: Const | DefKind :: Ctor ( _, CtorKind :: Const ) , did) => {
22442263 assert_eq ! ( opt_self_ty, None ) ;
2245- let _ = self . prohibit_generic_args (
2246- path. segments . split_last ( ) . unwrap ( ) . 1 . iter ( ) ,
2247- GenericsArgsErrExtend :: None ,
2248- ) ;
2249- let args = self . lower_generic_args_of_path_segment (
2250- span,
2251- did,
2252- path. segments . last ( ) . unwrap ( ) ,
2253- ) ;
2264+ let [ leading_segments @ .., segment] = path. segments else { bug ! ( ) } ;
2265+ let _ = self
2266+ . prohibit_generic_args ( leading_segments. iter ( ) , GenericsArgsErrExtend :: None ) ;
2267+ let args = self . lower_generic_args_of_path_segment ( span, did, segment) ;
22542268 ty:: Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( did, args) )
22552269 }
22562270 Res :: Def ( DefKind :: AssocConst , did) => {
0 commit comments