@@ -1358,30 +1358,61 @@ fn impl_trait_ref(
1358
1358
. of_trait
1359
1359
. as_ref ( )
1360
1360
. map ( |ast_trait_ref| {
1361
- check_impl_constness (
1361
+ let selfty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
1362
+
1363
+ if let Some ( ErrorGuaranteed { .. } ) = check_impl_constness (
1362
1364
tcx,
1363
1365
tcx. is_const_trait_impl_raw ( def_id. to_def_id ( ) ) ,
1364
- ast_trait_ref,
1365
- ) ;
1366
- let selfty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
1367
- icx. astconv ( ) . instantiate_mono_trait_ref ( ast_trait_ref, selfty)
1366
+ & ast_trait_ref,
1367
+ ) {
1368
+ // we have a const impl, but for a trait without `#[const_trait]`, so
1369
+ // without the host param. If we continue with the HIR trait ref, we get
1370
+ // ICEs for generic arg count mismatch. We do a little HIR editing to
1371
+ // make astconv happy.
1372
+ let mut path_segments = ast_trait_ref. path . segments . to_vec ( ) ;
1373
+ let last_segment = path_segments. len ( ) - 1 ;
1374
+ let mut args = path_segments[ last_segment] . args ( ) . clone ( ) ;
1375
+ let last_arg = args. args . len ( ) - 1 ;
1376
+ assert ! ( matches!( args. args[ last_arg] , hir:: GenericArg :: Const ( anon_const) if tcx. has_attr( anon_const. value. def_id, sym:: rustc_host) ) ) ;
1377
+ args. args = & args. args [ ..args. args . len ( ) - 1 ] ;
1378
+ path_segments[ last_segment] . args = Some ( & args) ;
1379
+ let path = hir:: Path {
1380
+ span : ast_trait_ref. path . span ,
1381
+ res : ast_trait_ref. path . res ,
1382
+ segments : & path_segments,
1383
+ } ;
1384
+ let trait_ref = hir:: TraitRef { path : & path, hir_ref_id : ast_trait_ref. hir_ref_id } ;
1385
+ icx. astconv ( ) . instantiate_mono_trait_ref ( & trait_ref, selfty)
1386
+ } else {
1387
+ icx. astconv ( ) . instantiate_mono_trait_ref ( & ast_trait_ref, selfty)
1388
+ }
1368
1389
} )
1369
1390
. map ( ty:: EarlyBinder :: bind)
1370
1391
}
1371
1392
1372
- fn check_impl_constness ( tcx : TyCtxt < ' _ > , is_const : bool , ast_trait_ref : & hir:: TraitRef < ' _ > ) {
1373
- if is_const {
1374
- if let Some ( trait_def_id) = ast_trait_ref. trait_def_id ( ) && !tcx. has_attr ( trait_def_id, sym:: const_trait) {
1375
- let trait_name = tcx. item_name ( trait_def_id) . to_string ( ) ;
1376
- tcx. sess . emit_err ( errors:: ConstImplForNonConstTrait {
1377
- trait_ref_span : ast_trait_ref. path . span ,
1378
- trait_name,
1379
- local_trait_span : trait_def_id. as_local ( ) . map ( |_| tcx. def_span ( trait_def_id) . shrink_to_lo ( ) ) ,
1380
- marking : ( ) ,
1381
- adding : ( ) ,
1382
- } ) ;
1383
- }
1393
+ fn check_impl_constness (
1394
+ tcx : TyCtxt < ' _ > ,
1395
+ is_const : bool ,
1396
+ ast_trait_ref : & hir:: TraitRef < ' _ > ,
1397
+ ) -> Option < ErrorGuaranteed > {
1398
+ if !is_const {
1399
+ return None ;
1384
1400
}
1401
+
1402
+ let trait_def_id = ast_trait_ref. trait_def_id ( ) ?;
1403
+ if tcx. has_attr ( trait_def_id, sym:: const_trait) {
1404
+ return None ;
1405
+ }
1406
+
1407
+ let trait_name = tcx. item_name ( trait_def_id) . to_string ( ) ;
1408
+ Some ( tcx. sess . emit_err ( errors:: ConstImplForNonConstTrait {
1409
+ trait_ref_span : ast_trait_ref. path . span ,
1410
+ trait_name,
1411
+ local_trait_span :
1412
+ trait_def_id. as_local ( ) . map ( |_| tcx. def_span ( trait_def_id) . shrink_to_lo ( ) ) ,
1413
+ marking : ( ) ,
1414
+ adding : ( ) ,
1415
+ } ) )
1385
1416
}
1386
1417
1387
1418
fn impl_polarity ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> ty:: ImplPolarity {
0 commit comments