From 057be381c60bf9b5c26497a42ad51917c3027b65 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 6 Aug 2023 17:00:26 +0000 Subject: [PATCH] Fix ICE --- compiler/rustc_ast_lowering/src/lib.rs | 16 ++++- compiler/rustc_hir_analysis/src/collect.rs | 65 ++++++++++++++----- .../consts/rustc-impl-const-stability.stderr | 11 +--- .../const-impl-requires-const-trait.stderr | 15 +---- .../derive-const-non-const-type.stderr | 11 +--- 5 files changed, 65 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index dd081fafafb..8953c4fb27a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2746,9 +2746,9 @@ impl<'hir> GenericArgsCtor<'hir> { span, res, segments: arena_vec![lcx; hir::PathSegment::new(Ident { - name: sym::host, - span, - }, hir_id, res)], + name: sym::host, + span, + }, hir_id, res)], }), )); lcx.expr(span, expr_kind) @@ -2762,6 +2762,16 @@ impl<'hir> GenericArgsCtor<'hir> { }, ) }); + + let attr_id = lcx.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(); + let attr = lcx.arena.alloc(Attribute { + kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))), + span, + id: attr_id, + style: AttrStyle::Outer, + }); + lcx.attrs.insert(hir_id.local_id, std::slice::from_ref(attr)); + let def_id = lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span); lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index c65cd25f12c..02a5d28b1e2 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1358,30 +1358,61 @@ fn impl_trait_ref( .of_trait .as_ref() .map(|ast_trait_ref| { - check_impl_constness( + let selfty = tcx.type_of(def_id).instantiate_identity(); + + if let Some(ErrorGuaranteed { .. }) = check_impl_constness( tcx, tcx.is_const_trait_impl_raw(def_id.to_def_id()), - ast_trait_ref, - ); - let selfty = tcx.type_of(def_id).instantiate_identity(); - icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty) + &ast_trait_ref, + ) { + // we have a const impl, but for a trait without `#[const_trait]`, so + // without the host param. If we continue with the HIR trait ref, we get + // ICEs for generic arg count mismatch. We do a little HIR editing to + // make astconv happy. + let mut path_segments = ast_trait_ref.path.segments.to_vec(); + let last_segment = path_segments.len() - 1; + let mut args = path_segments[last_segment].args().clone(); + let last_arg = args.args.len() - 1; + assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if tcx.has_attr(anon_const.value.def_id, sym::rustc_host))); + args.args = &args.args[..args.args.len() - 1]; + path_segments[last_segment].args = Some(&args); + let path = hir::Path { + span: ast_trait_ref.path.span, + res: ast_trait_ref.path.res, + segments: &path_segments, + }; + let trait_ref = hir::TraitRef { path: &path, hir_ref_id: ast_trait_ref.hir_ref_id }; + icx.astconv().instantiate_mono_trait_ref(&trait_ref, selfty) + } else { + icx.astconv().instantiate_mono_trait_ref(&ast_trait_ref, selfty) + } }) .map(ty::EarlyBinder::bind) } -fn check_impl_constness(tcx: TyCtxt<'_>, is_const: bool, ast_trait_ref: &hir::TraitRef<'_>) { - if is_const { - if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) { - let trait_name = tcx.item_name(trait_def_id).to_string(); - tcx.sess.emit_err(errors::ConstImplForNonConstTrait { - trait_ref_span: ast_trait_ref.path.span, - trait_name, - local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()), - marking: (), - adding: (), - }); - } +fn check_impl_constness( + tcx: TyCtxt<'_>, + is_const: bool, + ast_trait_ref: &hir::TraitRef<'_>, +) -> Option { + if !is_const { + return None; } + + let trait_def_id = ast_trait_ref.trait_def_id()?; + if tcx.has_attr(trait_def_id, sym::const_trait) { + return None; + } + + let trait_name = tcx.item_name(trait_def_id).to_string(); + Some(tcx.sess.emit_err(errors::ConstImplForNonConstTrait { + trait_ref_span: ast_trait_ref.path.span, + trait_name, + local_trait_span: + trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()), + marking: (), + adding: (), + })) } fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity { diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr index 7992bfe7752..ba8e6c1555c 100644 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -7,12 +7,6 @@ LL | impl const Default for Data { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0107]: missing generics for trait `Default` - --> $DIR/rustc-impl-const-stability.rs:15:12 - | -LL | impl const Default for Data { - | ^^^^^^^ expected 18446744073709551615 generic arguments - error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates --> $DIR/rustc-impl-const-stability.rs:15:6 | @@ -22,7 +16,6 @@ LL | impl const Default for Data { = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0207. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr index becb2ca1042..c45af1a9f8a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr @@ -10,18 +10,5 @@ LL | impl const A for () {} = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0107]: missing generics for trait `A` - --> $DIR/const-impl-requires-const-trait.rs:8:12 - | -LL | impl const A for () {} - | ^ expected 18446744073709551615 generic arguments - | -note: trait defined here, with 18446744073709551615 generic parameters: - --> $DIR/const-impl-requires-const-trait.rs:5:11 - | -LL | pub trait A {} - | ^ +error: aborting due to previous error -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 7d7518a887f..1c69ad43171 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -8,14 +8,5 @@ LL | #[derive_const(Default)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0107]: missing generics for trait `Default` - --> $DIR/derive-const-non-const-type.rs:10:16 - | -LL | #[derive_const(Default)] - | ^^^^^^^ expected 18446744073709551615 generic arguments - | - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) +error: aborting due to previous error -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0107`.