about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2023-08-06 17:00:26 +0000
committerDeadbeef <ent3rm4n@gmail.com>2023-08-07 17:16:10 +0000
commit057be381c60bf9b5c26497a42ad51917c3027b65 (patch)
tree650003e4197d75ab59295a5ac662ad49c81c6dbb
parent6c1e3bb6e97f4c6d760859c4e804f98b8cc64fe2 (diff)
downloadrust-057be381c60bf9b5c26497a42ad51917c3027b65.tar.gz
rust-057be381c60bf9b5c26497a42ad51917c3027b65.zip
Fix ICE
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs65
-rw-r--r--tests/ui/consts/rustc-impl-const-stability.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr15
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr11
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<ErrorGuaranteed> {
+    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 2 previous errors
+error: aborting due to previous error
 
-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 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0107`.