Rollup merge of #117403 - oli-obk:the_gift_that_keeps_on_giving_116849, r=compiler-errors
Poison check_well_formed if method receivers are invalid to prevent typeck from running on it fixes #117379 Though if some code invokes typeck without having first invoked `check_well_formed` then we'll encounter this ICE again. This can happen in const and const fn bodies if they are evaluated due to other `check_well_formed` checks or similar
This commit is contained in:
commit
24c6b6c803
@ -94,7 +94,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
|
|||||||
f: F,
|
f: F,
|
||||||
) -> Result<(), ErrorGuaranteed>
|
) -> Result<(), ErrorGuaranteed>
|
||||||
where
|
where
|
||||||
F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>),
|
F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>) -> Result<(), ErrorGuaranteed>,
|
||||||
{
|
{
|
||||||
let param_env = tcx.param_env(body_def_id);
|
let param_env = tcx.param_env(body_def_id);
|
||||||
let infcx = &tcx.infer_ctxt().build();
|
let infcx = &tcx.infer_ctxt().build();
|
||||||
@ -105,7 +105,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
|
|||||||
if !tcx.features().trivial_bounds {
|
if !tcx.features().trivial_bounds {
|
||||||
wfcx.check_false_global_bounds()
|
wfcx.check_false_global_bounds()
|
||||||
}
|
}
|
||||||
f(&mut wfcx);
|
f(&mut wfcx)?;
|
||||||
|
|
||||||
let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?;
|
let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?;
|
||||||
|
|
||||||
@ -875,6 +875,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
|
|||||||
ty,
|
ty,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
);
|
);
|
||||||
|
Ok(())
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let mut diag = match ty.kind() {
|
let mut diag = match ty.kind() {
|
||||||
@ -961,6 +962,7 @@ fn check_associated_item(
|
|||||||
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
||||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
ty::AssocKind::Fn => {
|
ty::AssocKind::Fn => {
|
||||||
let sig = tcx.fn_sig(item.def_id).instantiate_identity();
|
let sig = tcx.fn_sig(item.def_id).instantiate_identity();
|
||||||
@ -972,7 +974,7 @@ fn check_associated_item(
|
|||||||
hir_sig.decl,
|
hir_sig.decl,
|
||||||
item.def_id.expect_local(),
|
item.def_id.expect_local(),
|
||||||
);
|
);
|
||||||
check_method_receiver(wfcx, hir_sig, item, self_ty);
|
check_method_receiver(wfcx, hir_sig, item, self_ty)
|
||||||
}
|
}
|
||||||
ty::AssocKind::Type => {
|
ty::AssocKind::Type => {
|
||||||
if let ty::AssocItemContainer::TraitContainer = item.container {
|
if let ty::AssocItemContainer::TraitContainer = item.container {
|
||||||
@ -983,6 +985,7 @@ fn check_associated_item(
|
|||||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1097,6 +1100,7 @@ fn check_type_defn<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_where_clauses(wfcx, item.span, item.owner_id.def_id);
|
check_where_clauses(wfcx, item.span, item.owner_id.def_id);
|
||||||
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1121,7 +1125,8 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuarant
|
|||||||
}
|
}
|
||||||
|
|
||||||
let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
|
let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
|
||||||
check_where_clauses(wfcx, item.span, def_id)
|
check_where_clauses(wfcx, item.span, def_id);
|
||||||
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only check traits, don't check trait aliases
|
// Only check traits, don't check trait aliases
|
||||||
@ -1164,6 +1169,7 @@ fn check_item_fn(
|
|||||||
enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
|
enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
|
||||||
let sig = tcx.fn_sig(def_id).instantiate_identity();
|
let sig = tcx.fn_sig(def_id).instantiate_identity();
|
||||||
check_fn_or_method(wfcx, ident.span, sig, decl, def_id);
|
check_fn_or_method(wfcx, ident.span, sig, decl, def_id);
|
||||||
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1218,6 +1224,7 @@ fn check_item_type(
|
|||||||
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
|
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1276,6 +1283,7 @@ fn check_impl<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_where_clauses(wfcx, item.span, item.owner_id.def_id);
|
check_where_clauses(wfcx, item.span, item.owner_id.def_id);
|
||||||
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1548,11 +1556,11 @@ fn check_method_receiver<'tcx>(
|
|||||||
fn_sig: &hir::FnSig<'_>,
|
fn_sig: &hir::FnSig<'_>,
|
||||||
method: ty::AssocItem,
|
method: ty::AssocItem,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
) {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let tcx = wfcx.tcx();
|
let tcx = wfcx.tcx();
|
||||||
|
|
||||||
if !method.fn_has_self_parameter {
|
if !method.fn_has_self_parameter {
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = fn_sig.decl.inputs[0].span;
|
let span = fn_sig.decl.inputs[0].span;
|
||||||
@ -1571,11 +1579,11 @@ fn check_method_receiver<'tcx>(
|
|||||||
if tcx.features().arbitrary_self_types {
|
if tcx.features().arbitrary_self_types {
|
||||||
if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
|
if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
|
||||||
// Report error; `arbitrary_self_types` was enabled.
|
// Report error; `arbitrary_self_types` was enabled.
|
||||||
e0307(tcx, span, receiver_ty);
|
return Err(e0307(tcx, span, receiver_ty));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, false) {
|
if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, false) {
|
||||||
if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
|
return Err(if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
|
||||||
// Report error; would have worked with `arbitrary_self_types`.
|
// Report error; would have worked with `arbitrary_self_types`.
|
||||||
feature_err(
|
feature_err(
|
||||||
&tcx.sess.parse_sess,
|
&tcx.sess.parse_sess,
|
||||||
@ -1587,16 +1595,17 @@ fn check_method_receiver<'tcx>(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.help(HELP_FOR_SELF_TYPE)
|
.help(HELP_FOR_SELF_TYPE)
|
||||||
.emit();
|
.emit()
|
||||||
} else {
|
} else {
|
||||||
// Report error; would not have worked with `arbitrary_self_types`.
|
// Report error; would not have worked with `arbitrary_self_types`.
|
||||||
e0307(tcx, span, receiver_ty);
|
e0307(tcx, span, receiver_ty)
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) {
|
fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) -> ErrorGuaranteed {
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
tcx.sess.diagnostic(),
|
tcx.sess.diagnostic(),
|
||||||
span,
|
span,
|
||||||
@ -1605,7 +1614,7 @@ fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) {
|
|||||||
)
|
)
|
||||||
.note("type of `self` must be `Self` or a type that dereferences to it")
|
.note("type of `self` must be `Self` or a type that dereferences to it")
|
||||||
.help(HELP_FOR_SELF_TYPE)
|
.help(HELP_FOR_SELF_TYPE)
|
||||||
.emit();
|
.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
|
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature
|
||||||
|
--> $DIR/arbitrary-self-from-method-substs.rs:8:43
|
||||||
|
|
|
||||||
|
LL | fn get<R: Deref<Target = Self>>(self: R) -> u32 {
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
|
||||||
|
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
|
||||||
|
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
@ -1,5 +1,5 @@
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/arbitrary-self-from-method-substs.rs:14:5
|
--> $DIR/arbitrary-self-from-method-substs.rs:16:5
|
||||||
|
|
|
|
||||||
LL | foo.get::<&Foo>();
|
LL | foo.get::<&Foo>();
|
||||||
| ^^^ expected `&Foo`, found `Foo`
|
| ^^^ expected `&Foo`, found `Foo`
|
@ -1,10 +1,12 @@
|
|||||||
#![feature(arbitrary_self_types)]
|
// revisions: default feature
|
||||||
|
#![cfg_attr(feature, feature(arbitrary_self_types))]
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
struct Foo(u32);
|
struct Foo(u32);
|
||||||
impl Foo {
|
impl Foo {
|
||||||
fn get<R: Deref<Target=Self>>(self: R) -> u32 {
|
fn get<R: Deref<Target = Self>>(self: R) -> u32 {
|
||||||
|
//[default]~^ ERROR: `R` cannot be used as the type of `self`
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12,5 +14,5 @@ fn get<R: Deref<Target=Self>>(self: R) -> u32 {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let mut foo = Foo(1);
|
let mut foo = Foo(1);
|
||||||
foo.get::<&Foo>();
|
foo.get::<&Foo>();
|
||||||
//~^ ERROR mismatched types
|
//[feature]~^ ERROR mismatched types
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user