Auto merge of #120558 - oli-obk:missing_impl_item_ice, r=estebank
Stop bailing out from compilation just because there were incoherent traits fixes #120343 but also has a lot of "type annotations needed" fallout. Some are fixed in the second commit.
This commit is contained in:
commit
870a01a30e
50 changed files with 490 additions and 146 deletions
|
@ -1990,6 +1990,10 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
impl_ty: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
|
||||
// other `Foo` impls are incoherent.
|
||||
tcx.ensure().coherent_trait(impl_trait_ref.def_id)?;
|
||||
|
||||
let param_env = tcx.param_env(impl_ty.def_id);
|
||||
debug!(?param_env);
|
||||
|
||||
|
|
|
@ -1005,6 +1005,11 @@ fn check_associated_item(
|
|||
enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| {
|
||||
let item = tcx.associated_item(item_id);
|
||||
|
||||
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
|
||||
// other `Foo` impls are incoherent.
|
||||
tcx.ensure()
|
||||
.coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?;
|
||||
|
||||
let self_ty = match item.container {
|
||||
ty::TraitContainer => tcx.types.self_param,
|
||||
ty::ImplContainer => tcx.type_of(item.container_id(tcx)).instantiate_identity(),
|
||||
|
@ -1291,6 +1296,9 @@ fn check_impl<'tcx>(
|
|||
// therefore don't need to be WF (the trait's `Self: Trait` predicate
|
||||
// won't hold).
|
||||
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity();
|
||||
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
|
||||
// other `Foo` impls are incoherent.
|
||||
tcx.ensure().coherent_trait(trait_ref.def_id)?;
|
||||
let trait_ref = wfcx.normalize(
|
||||
ast_trait_ref.path.span,
|
||||
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
||||
|
|
|
@ -169,11 +169,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
|||
|
||||
tcx.sess.time("coherence_checking", || {
|
||||
// Check impls constrain their parameters
|
||||
let mut res =
|
||||
let res =
|
||||
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module));
|
||||
|
||||
for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
|
||||
res = res.and(tcx.ensure().coherent_trait(trait_def_id));
|
||||
let _ = tcx.ensure().coherent_trait(trait_def_id);
|
||||
}
|
||||
// these queries are executed for side-effects (error reporting):
|
||||
res.and(tcx.ensure().crate_inherent_impls(()))
|
||||
|
|
|
@ -41,7 +41,7 @@ pub fn check_legal_trait_for_method_call(
|
|||
receiver: Option<Span>,
|
||||
expr_span: Span,
|
||||
trait_id: DefId,
|
||||
) {
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
if tcx.lang_items().drop_trait() == Some(trait_id) {
|
||||
let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) {
|
||||
errors::ExplicitDestructorCallSugg::Snippet {
|
||||
|
@ -51,8 +51,9 @@ pub fn check_legal_trait_for_method_call(
|
|||
} else {
|
||||
errors::ExplicitDestructorCallSugg::Empty(span)
|
||||
};
|
||||
tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg });
|
||||
return Err(tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg }));
|
||||
}
|
||||
tcx.coherent_trait(trait_id)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -1105,13 +1105,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let container_id = assoc_item.container_id(tcx);
|
||||
debug!(?def_id, ?container, ?container_id);
|
||||
match container {
|
||||
ty::TraitContainer => callee::check_legal_trait_for_method_call(
|
||||
tcx,
|
||||
path_span,
|
||||
None,
|
||||
span,
|
||||
container_id,
|
||||
),
|
||||
ty::TraitContainer => {
|
||||
if let Err(e) = callee::check_legal_trait_for_method_call(
|
||||
tcx,
|
||||
path_span,
|
||||
None,
|
||||
span,
|
||||
container_id,
|
||||
) {
|
||||
self.set_tainted_by_errors(e);
|
||||
}
|
||||
}
|
||||
ty::ImplContainer => {
|
||||
if segments.len() == 1 {
|
||||
// `<T>::assoc` will end up here, and so
|
||||
|
|
|
@ -630,13 +630,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) {
|
||||
// Disallow calls to the method `drop` defined in the `Drop` trait.
|
||||
if let Some(trait_def_id) = pick.item.trait_container(self.tcx) {
|
||||
callee::check_legal_trait_for_method_call(
|
||||
if let Err(e) = callee::check_legal_trait_for_method_call(
|
||||
self.tcx,
|
||||
self.span,
|
||||
Some(self.self_expr.span),
|
||||
self.call_expr.span,
|
||||
trait_def_id,
|
||||
)
|
||||
) {
|
||||
self.set_tainted_by_errors(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2371,6 +2371,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
return e;
|
||||
}
|
||||
|
||||
if let Err(guar) = self.tcx.ensure().coherent_trait(trait_ref.def_id()) {
|
||||
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
|
||||
// other `Foo` impls are incoherent.
|
||||
return guar;
|
||||
}
|
||||
|
||||
// This is kind of a hack: it frequently happens that some earlier
|
||||
// error prevents types from being fully inferred, and then we get
|
||||
// a bunch of uninteresting errors saying something like "<generic
|
||||
|
@ -2666,6 +2672,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
if let Some(e) = self.tainted_by_errors() {
|
||||
return e;
|
||||
}
|
||||
|
||||
if let Err(guar) =
|
||||
self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_ty.def_id))
|
||||
{
|
||||
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
|
||||
// other `Foo` impls are incoherent.
|
||||
return guar;
|
||||
}
|
||||
let subst = data
|
||||
.projection_ty
|
||||
.args
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue