1
Fork 0

Move call trait lang item malformed check to typeck

This commit is contained in:
Michael Goulet 2023-02-16 20:32:59 +00:00
parent c5283576ec
commit 3dd638fe6c
12 changed files with 170 additions and 71 deletions

View file

@ -16,7 +16,7 @@ use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{
self, ir::TypeVisitor, AdtKind, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable,
self, ir::TypeVisitor, AdtKind, GenericParamDefKind, Ty, TyCtxt, TypeFoldable,
TypeSuperVisitable,
};
use rustc_middle::ty::{GenericArgKind, InternalSubsts};
@ -277,56 +277,6 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
};
check_object_unsafe_self_trait_by_name(tcx, trait_item);
check_associated_item(tcx, def_id, span, method_sig);
let encl_trait_def_id = tcx.local_parent(def_id);
let encl_trait = tcx.hir().expect_item(encl_trait_def_id);
let encl_trait_def_id = encl_trait.owner_id.to_def_id();
let fn_lang_item_name = if Some(encl_trait_def_id) == tcx.lang_items().fn_trait() {
Some("fn")
} else if Some(encl_trait_def_id) == tcx.lang_items().fn_mut_trait() {
Some("fn_mut")
} else {
None
};
if let (Some(fn_lang_item_name), "call") =
(fn_lang_item_name, trait_item.ident.name.to_ident_string().as_str())
{
// We are looking at the `call` function of the `fn` or `fn_mut` lang item.
// Do some rudimentary sanity checking to avoid an ICE later (issue #83471).
if let Some(hir::FnSig { decl, span, .. }) = method_sig {
if let [self_ty, _] = decl.inputs {
if !matches!(self_ty.kind, hir::TyKind::Ref(_, _)) {
tcx.sess
.struct_span_err(
self_ty.span,
&format!(
"first argument of `call` in `{fn_lang_item_name}` lang item must be a reference",
),
)
.emit();
}
} else {
tcx.sess
.struct_span_err(
*span,
&format!(
"`call` function in `{fn_lang_item_name}` lang item takes exactly two arguments",
),
)
.emit();
}
} else {
tcx.sess
.struct_span_err(
trait_item.span,
&format!(
"`call` trait item in `{fn_lang_item_name}` lang item must be a function",
),
)
.emit();
}
}
}
/// Require that the user writes where clauses on GATs for the implicit

View file

@ -380,6 +380,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
return None;
};
if method_item.kind != ty::AssocKind::Fn {
self.tcx.sess.delay_span_bug(tcx.def_span(method_item.def_id), "not a method");
return None;
}
let def_id = method_item.def_id;
let generics = tcx.generics_of(def_id);

View file

@ -0,0 +1,18 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:39:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:43:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: aborting due to 2 previous errors

View file

@ -0,0 +1,18 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:39:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:43:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: aborting due to 2 previous errors

View file

@ -0,0 +1,18 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: aborting due to 2 previous errors

View file

@ -0,0 +1,18 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: aborting due to 2 previous errors

View file

@ -0,0 +1,18 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: aborting due to 2 previous errors

View file

@ -0,0 +1,18 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: aborting due to 2 previous errors

View file

@ -0,0 +1,18 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
error: aborting due to 2 previous errors

View file

@ -0,0 +1,9 @@
error[E0308]: mismatched types
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^ expected `i32`, found `()`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,27 +1,49 @@
// Make sure that an error is reported if the `call` function of the
// `fn`/`fn_mut` lang item is grossly ill-formed.
// revisions: fn_once_bad_item fn_once_bad_sig fn_mut_bad_item fn_mut_bad_sig fn_bad_item fn_bad_sig
#![feature(lang_items)]
#![feature(no_core)]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[cfg(any(fn_bad_item, fn_bad_sig))]
#[lang = "fn"]
trait MyFn<T> {
#[cfg(fn_bad_sig)]
fn call(i: i32) -> i32 { 0 }
#[cfg(fn_bad_item)]
const call: i32 = 42;
//~^ ERROR: `call` trait item in `fn` lang item must be a function
}
#[cfg(any(fn_mut_bad_item, fn_mut_bad_sig))]
#[lang = "fn_mut"]
trait MyFnMut<T> {
fn call(i: i32, j: i32) -> i32 { i + j }
//~^ ERROR: first argument of `call` in `fn_mut` lang item must be a reference
#[cfg(fn_mut_bad_sig)]
fn call_mut(i: i32) -> i32 { 0 }
#[cfg(fn_mut_bad_item)]
const call_mut: i32 = 42;
}
#[cfg(any(fn_once_bad_item, fn_once_bad_sig))]
#[lang = "fn_once"]
trait MyFnOnce<T> {
#[cfg(fn_once_bad_sig)]
fn call_once(i: i32) -> i32 { 0 }
#[cfg(fn_once_bad_item)]
const call_once: i32 = 42;
}
fn main() {
let a = || 42;
a();
//~^ ERROR failed to find an overloaded call trait for closure call
let mut i = 0;
let mut b = || { i += 1; };
let mut b = || { };
b();
//~^ ERROR failed to find an overloaded call trait for closure call
}

View file

@ -1,14 +0,0 @@
error: `call` trait item in `fn` lang item must be a function
--> $DIR/fn-fn_mut-call-ill-formed.rs:10:5
|
LL | const call: i32 = 42;
| ^^^^^^^^^^^^^^^^^^^^^
error: first argument of `call` in `fn_mut` lang item must be a reference
--> $DIR/fn-fn_mut-call-ill-formed.rs:16:16
|
LL | fn call(i: i32, j: i32) -> i32 { i + j }
| ^^^
error: aborting due to 2 previous errors