From: Yuki Okushi Date: Thu, 1 Jul 2021 21:20:28 +0000 (+0900) Subject: Rollup merge of #86148 - FabianWolff:issue-85855, r=varkor X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=ab4d16fe7abbbc14617e2d5c311578034b9f1646;p=rust.git Rollup merge of #86148 - FabianWolff:issue-85855, r=varkor 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. --- ab4d16fe7abbbc14617e2d5c311578034b9f1646 diff --cc compiler/rustc_typeck/src/check/intrinsic.rs index a259fc6a488,38ace42618b..a56aefcef9c --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@@ -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