Skip to content

Commit 057be38

Browse files
committed
Fix ICE
1 parent 6c1e3bb commit 057be38

File tree

5 files changed

+65
-53
lines changed

5 files changed

+65
-53
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -2746,9 +2746,9 @@ impl<'hir> GenericArgsCtor<'hir> {
27462746
span,
27472747
res,
27482748
segments: arena_vec![lcx; hir::PathSegment::new(Ident {
2749-
name: sym::host,
2750-
span,
2751-
}, hir_id, res)],
2749+
name: sym::host,
2750+
span,
2751+
}, hir_id, res)],
27522752
}),
27532753
));
27542754
lcx.expr(span, expr_kind)
@@ -2762,6 +2762,16 @@ impl<'hir> GenericArgsCtor<'hir> {
27622762
},
27632763
)
27642764
});
2765+
2766+
let attr_id = lcx.tcx.sess.parse_sess.attr_id_generator.mk_attr_id();
2767+
let attr = lcx.arena.alloc(Attribute {
2768+
kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))),
2769+
span,
2770+
id: attr_id,
2771+
style: AttrStyle::Outer,
2772+
});
2773+
lcx.attrs.insert(hir_id.local_id, std::slice::from_ref(attr));
2774+
27652775
let def_id =
27662776
lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span);
27672777
lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));

compiler/rustc_hir_analysis/src/collect.rs

+48-17
Original file line numberDiff line numberDiff line change
@@ -1358,30 +1358,61 @@ fn impl_trait_ref(
13581358
.of_trait
13591359
.as_ref()
13601360
.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(
13621364
tcx,
13631365
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+
}
13681389
})
13691390
.map(ty::EarlyBinder::bind)
13701391
}
13711392

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;
13841400
}
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+
}))
13851416
}
13861417

13871418
fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity {

tests/ui/consts/rustc-impl-const-stability.stderr

+2-9
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ LL | impl const Default for Data {
77
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
88
= note: adding a non-const method body in the future would be a breaking change
99

10-
error[E0107]: missing generics for trait `Default`
11-
--> $DIR/rustc-impl-const-stability.rs:15:12
12-
|
13-
LL | impl const Default for Data {
14-
| ^^^^^^^ expected 18446744073709551615 generic arguments
15-
1610
error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
1711
--> $DIR/rustc-impl-const-stability.rs:15:6
1812
|
@@ -22,7 +16,6 @@ LL | impl const Default for Data {
2216
= note: expressions using a const parameter must map each value to a distinct output value
2317
= note: proving the result of expressions other than the parameter are unique is not supported
2418

25-
error: aborting due to 3 previous errors
19+
error: aborting due to 2 previous errors
2620

27-
Some errors have detailed explanations: E0107, E0207.
28-
For more information about an error, try `rustc --explain E0107`.
21+
For more information about this error, try `rustc --explain E0207`.

tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr

+1-14
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,5 @@ LL | impl const A for () {}
1010
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
1111
= note: adding a non-const method body in the future would be a breaking change
1212

13-
error[E0107]: missing generics for trait `A`
14-
--> $DIR/const-impl-requires-const-trait.rs:8:12
15-
|
16-
LL | impl const A for () {}
17-
| ^ expected 18446744073709551615 generic arguments
18-
|
19-
note: trait defined here, with 18446744073709551615 generic parameters:
20-
--> $DIR/const-impl-requires-const-trait.rs:5:11
21-
|
22-
LL | pub trait A {}
23-
| ^
24-
25-
error: aborting due to 2 previous errors
13+
error: aborting due to previous error
2614

27-
For more information about this error, try `rustc --explain E0107`.

tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr

+1-10
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,5 @@ LL | #[derive_const(Default)]
88
= note: adding a non-const method body in the future would be a breaking change
99
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
1010

11-
error[E0107]: missing generics for trait `Default`
12-
--> $DIR/derive-const-non-const-type.rs:10:16
13-
|
14-
LL | #[derive_const(Default)]
15-
| ^^^^^^^ expected 18446744073709551615 generic arguments
16-
|
17-
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
18-
19-
error: aborting due to 2 previous errors
11+
error: aborting due to previous error
2012

21-
For more information about this error, try `rustc --explain E0107`.

0 commit comments

Comments
 (0)