@@ -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,67 @@ 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
776- // Relaxed bounds `?Trait` and `PointeeSized` bounds aren't represented in the ` middle::ty` IR
778+ // 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+ } ;
797+ let bounds = if transient { & mut Vec :: new ( ) } else { bounds } ;
795798
796- ( ty:: PredicatePolarity :: Positive , & mut Vec :: new ( ) )
799+ let polarity = match polarity {
800+ hir:: BoundPolarity :: Positive | hir:: BoundPolarity :: Maybe ( _) => {
801+ ty:: PredicatePolarity :: Positive
797802 }
803+ hir:: BoundPolarity :: Negative ( _) => ty:: PredicatePolarity :: Negative ,
798804 } ;
799805
800- let trait_segment = trait_ref. path . segments . last ( ) . unwrap ( ) ;
806+ let [ leading_segments @ .. , segment ] = trait_ref. path . segments else { bug ! ( ) } ;
801807
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 ) ;
808+ let _ = self . prohibit_generic_args ( leading_segments. iter ( ) , GenericsArgsErrExtend :: None ) ;
809+ self . report_internal_fn_trait ( span, trait_def_id, segment, false ) ;
807810
808811 let ( generic_args, arg_count) = self . lower_generic_args_of_path (
809812 trait_ref. path . span ,
810813 trait_def_id,
811814 & [ ] ,
812- trait_segment ,
815+ segment ,
813816 Some ( self_ty) ,
814817 ) ;
815818
819+ let constraints = segment. args ( ) . constraints ;
820+
821+ if transient && ( !generic_args[ 1 ..] . is_empty ( ) || !constraints. is_empty ( ) ) {
822+ // Since the bound won't be present in the middle::ty IR as established above, any
823+ // arguments or constraints won't be checked for well-formedness in later passes.
824+ //
825+ // This is only an issue if the trait ref is otherwise valid which can only happen if
826+ // the corresponding default trait has generic parameters or associated items. Such a
827+ // trait would be degenerate. We delay a bug to detect and guard us against these.
828+ //
829+ // E.g: Given `/*default*/ trait Bound<'a: 'static, T, const N: usize> {}`,
830+ // `?Bound<Vec<str>, { panic!() }>` won't be wfchecked.
831+ self . dcx ( )
832+ . span_delayed_bug ( span, "transient bound should not have args or constraints" ) ;
833+ }
834+
816835 let bound_vars = tcx. late_bound_vars ( trait_ref. hir_ref_id ) ;
817836 debug ! ( ?bound_vars) ;
818837
@@ -924,7 +943,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
924943 == OverlappingAsssocItemConstraints :: Forbidden )
925944 . then_some ( FxIndexMap :: default ( ) ) ;
926945
927- for constraint in trait_segment . args ( ) . constraints {
946+ for constraint in constraints {
928947 // Don't register any associated item constraints for negative bounds,
929948 // since we should have emitted an error for them earlier, and they
930949 // would not be well-formed!
@@ -1916,10 +1935,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19161935 Res :: Def ( DefKind :: OpaqueTy , did) => {
19171936 // Check for desugared `impl Trait`.
19181937 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 ) ;
1938+ let [ leading_segments @ .., segment] = path. segments else { bug ! ( ) } ;
1939+ let _ = self . prohibit_generic_args (
1940+ leading_segments. iter ( ) ,
1941+ GenericsArgsErrExtend :: OpaqueTy ,
1942+ ) ;
1943+ let args = self . lower_generic_args_of_path_segment ( span, did, segment) ;
19231944 Ty :: new_opaque ( tcx, did, args)
19241945 }
19251946 Res :: Def (
@@ -1931,11 +1952,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19311952 did,
19321953 ) => {
19331954 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 ( ) )
1955+ let [ leading_segments @ .., segment] = path. segments else { bug ! ( ) } ;
1956+ let _ = self
1957+ . prohibit_generic_args ( leading_segments. iter ( ) , GenericsArgsErrExtend :: None ) ;
1958+ self . lower_path_segment ( span, did, segment)
19391959 }
19401960 Res :: Def ( kind @ DefKind :: Variant , def_id)
19411961 if let PermitVariants :: Yes = permit_variants =>
@@ -1955,8 +1975,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19551975 GenericsArgsErrExtend :: DefVariant ( & path. segments ) ,
19561976 ) ;
19571977
1958- let GenericPathSegment ( def_id, index) = generic_segments. last ( ) . unwrap ( ) ;
1959- self . lower_path_segment ( span, * def_id, & path. segments [ * index] )
1978+ let & GenericPathSegment ( def_id, index) = generic_segments. last ( ) . unwrap ( ) ;
1979+ self . lower_path_segment ( span, def_id, & path. segments [ index] )
19601980 }
19611981 Res :: Def ( DefKind :: TyParam , def_id) => {
19621982 assert_eq ! ( opt_self_ty, None ) ;
@@ -2242,15 +2262,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22422262 }
22432263 Res :: Def ( DefKind :: Const | DefKind :: Ctor ( _, CtorKind :: Const ) , did) => {
22442264 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- ) ;
2265+ let [ leading_segments @ .., segment] = path. segments else { bug ! ( ) } ;
2266+ let _ = self
2267+ . prohibit_generic_args ( leading_segments. iter ( ) , GenericsArgsErrExtend :: None ) ;
2268+ let args = self . lower_generic_args_of_path_segment ( span, did, segment) ;
22542269 ty:: Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( did, args) )
22552270 }
22562271 Res :: Def ( DefKind :: AssocConst , did) => {
0 commit comments