]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #86148 - FabianWolff:issue-85855, r=varkor
authorYuki Okushi <jtitor@2k36.org>
Thu, 1 Jul 2021 21:20:28 +0000 (06:20 +0900)
committerGitHub <noreply@github.com>
Thu, 1 Jul 2021 21:20:28 +0000 (06:20 +0900)
Check the number of generic lifetime and const parameters of intrinsics

This pull request fixes #85855. The current code for type checking intrinsics only checks the number of generic _type_ parameters, but does not check for an incorrect number of lifetime or const parameters, which can cause problems later on, such as the ICE in #85855, where the code thought that it was looking at a type parameter but found a lifetime parameter:
```
error: internal compiler error: compiler/rustc_middle/src/ty/generics.rs:188:18:
    expected type parameter, but found another generic parameter
```

The changes in this PR add checks for the number of lifetime and const parameters, expand the scope of `E0094` to also apply to these cases, and improve the error message by properly pluralizing the number of expected generic parameters.

1  2 
compiler/rustc_typeck/src/check/intrinsic.rs
compiler/rustc_typeck/src/errors.rs

index a259fc6a488fc7ce881926a5cb8a3fa279e6d5f7,38ace42618bfcdd5fdd4903b5c40d5bb99a19357..a56aefcef9cdd78da7ae7630891eff9c5b8e40cd
@@@ -31,29 -35,34 +35,34 @@@ fn equate_intrinsic_type<'tcx>
                  .emit();
              return;
          }
-     }
+     };
  
-     let i_n_tps = tcx.generics_of(it.def_id).own_counts().types;
-     if i_n_tps != n_tps {
-         let span = match it.kind {
-             hir::ForeignItemKind::Fn(_, _, ref generics) => generics.span,
-             _ => bug!(),
-         };
+     let gen_count_ok = |found: usize, expected: usize, descr: &str| -> bool {
+         if found != expected {
+             tcx.sess.emit_err(WrongNumberOfGenericArgumentsToIntrinsic {
+                 span,
+                 found,
+                 expected,
+                 expected_pluralize: pluralize!(expected),
+                 descr,
+             });
+             false
+         } else {
+             true
+         }
+     };
  
-         tcx.sess.emit_err(WrongNumberOfTypeArgumentsToInstrinsic {
-             span,
-             found: i_n_tps,
-             expected: n_tps,
-         });
-         return;
+     if gen_count_ok(own_counts.lifetimes, n_lts, "lifetime")
+         && gen_count_ok(own_counts.types, n_tps, "type")
+         && gen_count_ok(own_counts.consts, 0, "const")
+     {
+         let fty = tcx.mk_fn_ptr(sig);
+         let cause = ObligationCause::new(it.span, it.hir_id(), ObligationCauseCode::IntrinsicType);
+         require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.def_id)), fty);
      }
-     let fty = tcx.mk_fn_ptr(sig);
-     let cause = ObligationCause::new(it.span, it.hir_id(), ObligationCauseCode::IntrinsicType);
-     require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.def_id)), fty);
  }
  
 -/// Returns `true` if the given intrinsic is unsafe to call or not.
 +/// Returns the unsafety of the given intrinsic.
  pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
      match intrinsic {
          sym::abort
Simple merge