Rollup merge of #150915 - eii-regression-test-149983, r=kivooeo
Regression test for type params on eii Somewhere along the line I fixed this one with my other PRs. This just adds the regression tests Closes rust-lang/rust#149983
This commit is contained in:
commit
0d3692a437
8 changed files with 73 additions and 4 deletions
|
|
@ -166,8 +166,9 @@ hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twic
|
|||
.label = parameter captured again here
|
||||
|
||||
hir_analysis_eii_with_generics =
|
||||
#[{$eii_name}] cannot have generic parameters other than lifetimes
|
||||
`{$impl_name}` cannot have generic parameters other than lifetimes
|
||||
.label = required by this attribute
|
||||
.help = `#[{$eii_name}]` marks the implementation of an "externally implementable item"
|
||||
|
||||
hir_analysis_empty_specialization = specialization impl does not specialize any associated items
|
||||
.note = impl is a specialization of this impl
|
||||
|
|
|
|||
|
|
@ -974,12 +974,19 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
|
|||
(0, _) => ("const", "consts", None),
|
||||
_ => ("type or const", "types or consts", None),
|
||||
};
|
||||
let name =
|
||||
if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::EiiForeignItem) {
|
||||
"externally implementable items"
|
||||
} else {
|
||||
"foreign items"
|
||||
};
|
||||
|
||||
let span = tcx.def_span(def_id);
|
||||
struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
span,
|
||||
E0044,
|
||||
"foreign items may not have {kinds} parameters",
|
||||
"{name} may not have {kinds} parameters",
|
||||
)
|
||||
.with_span_label(span, format!("can't have {kinds} parameters"))
|
||||
.with_help(
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ use std::iter;
|
|||
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_errors::{Applicability, E0806, struct_span_code_err};
|
||||
use rustc_hir::attrs::{AttributeKind, EiiImplResolution};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::{self as hir, FnSig, HirId, ItemKind};
|
||||
use rustc_hir::{self as hir, FnSig, HirId, ItemKind, find_attr};
|
||||
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
|
|
@ -169,11 +170,23 @@ fn check_no_generics<'tcx>(
|
|||
eii_attr_span: Span,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let generics = tcx.generics_of(external_impl);
|
||||
if generics.own_requires_monomorphization() {
|
||||
if generics.own_requires_monomorphization()
|
||||
// When an EII implementation is automatically generated by the `#[eii]` macro,
|
||||
// it will directly refer to the foreign item, not through a macro.
|
||||
// We don't want to emit this error if it's an implementation that's generated by the `#[eii]` macro,
|
||||
// since in that case it looks like a duplicate error: the declaration of the EII already can't contain generics.
|
||||
// So, we check here if at least one of the eii impls has ImplResolution::Macro, which indicates it's
|
||||
// not generated as part of the declaration.
|
||||
&& find_attr!(
|
||||
tcx.get_all_attrs(external_impl),
|
||||
AttributeKind::EiiImpls(impls) if impls.iter().any(|i| matches!(i.resolution, EiiImplResolution::Macro(_)))
|
||||
)
|
||||
{
|
||||
tcx.dcx().emit_err(EiiWithGenerics {
|
||||
span: tcx.def_span(external_impl),
|
||||
attr: eii_attr_span,
|
||||
eii_name,
|
||||
impl_name: tcx.item_name(external_impl),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1655,10 +1655,12 @@ pub(crate) struct LifetimesOrBoundsMismatchOnEii {
|
|||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_eii_with_generics)]
|
||||
#[help]
|
||||
pub(crate) struct EiiWithGenerics {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[label]
|
||||
pub attr: Span,
|
||||
pub eii_name: Symbol,
|
||||
pub impl_name: Symbol,
|
||||
}
|
||||
|
|
|
|||
13
tests/ui/eii/type_checking/generic_implementation.rs
Normal file
13
tests/ui/eii/type_checking/generic_implementation.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
//@ check-fail
|
||||
// Check that type parameters on EIIs are properly rejected.
|
||||
// Specifically a regression test for https://github.com/rust-lang/rust/issues/149983.
|
||||
#![feature(extern_item_impls)]
|
||||
|
||||
#[eii]
|
||||
fn foo();
|
||||
|
||||
#[foo]
|
||||
fn foo_impl<T>() {}
|
||||
//~^ ERROR `foo_impl` cannot have generic parameters other than lifetimes
|
||||
|
||||
fn main() {}
|
||||
12
tests/ui/eii/type_checking/generic_implementation.stderr
Normal file
12
tests/ui/eii/type_checking/generic_implementation.stderr
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
error: `foo_impl` cannot have generic parameters other than lifetimes
|
||||
--> $DIR/generic_implementation.rs:10:1
|
||||
|
|
||||
LL | #[foo]
|
||||
| ------ required by this attribute
|
||||
LL | fn foo_impl<T>() {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: `#[foo]` marks the implementation of an "externally implementable item"
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
10
tests/ui/eii/type_checking/type_params_149983.rs
Normal file
10
tests/ui/eii/type_checking/type_params_149983.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
//@ check-fail
|
||||
// Check that type parameters on EIIs are properly rejected.
|
||||
// Specifically a regression test for https://github.com/rust-lang/rust/issues/149983.
|
||||
#![feature(extern_item_impls)]
|
||||
|
||||
#[eii]
|
||||
fn foo<T>() {}
|
||||
//~^ ERROR externally implementable items may not have type parameters
|
||||
|
||||
fn main() {}
|
||||
11
tests/ui/eii/type_checking/type_params_149983.stderr
Normal file
11
tests/ui/eii/type_checking/type_params_149983.stderr
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
error[E0044]: externally implementable items may not have type parameters
|
||||
--> $DIR/type_params_149983.rs:7:1
|
||||
|
|
||||
LL | fn foo<T>() {}
|
||||
| ^^^^^^^^^^^ can't have type parameters
|
||||
|
|
||||
= help: replace the type parameters with concrete types like `u32`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0044`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue