Skip to content

Commit 24c6b6c

Browse files
authored
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
2 parents 342483c + ff3a818 commit 24c6b6c

4 files changed

+41
-17
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+22-13
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
9494
f: F,
9595
) -> Result<(), ErrorGuaranteed>
9696
where
97-
F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>),
97+
F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>) -> Result<(), ErrorGuaranteed>,
9898
{
9999
let param_env = tcx.param_env(body_def_id);
100100
let infcx = &tcx.infer_ctxt().build();
@@ -105,7 +105,7 @@ where
105105
if !tcx.features().trivial_bounds {
106106
wfcx.check_false_global_bounds()
107107
}
108-
f(&mut wfcx);
108+
f(&mut wfcx)?;
109109

110110
let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?;
111111

@@ -875,6 +875,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
875875
ty,
876876
trait_def_id,
877877
);
878+
Ok(())
878879
})
879880
} else {
880881
let mut diag = match ty.kind() {
@@ -961,6 +962,7 @@ fn check_associated_item(
961962
let ty = tcx.type_of(item.def_id).instantiate_identity();
962963
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
963964
wfcx.register_wf_obligation(span, loc, ty.into());
965+
Ok(())
964966
}
965967
ty::AssocKind::Fn => {
966968
let sig = tcx.fn_sig(item.def_id).instantiate_identity();
@@ -972,7 +974,7 @@ fn check_associated_item(
972974
hir_sig.decl,
973975
item.def_id.expect_local(),
974976
);
975-
check_method_receiver(wfcx, hir_sig, item, self_ty);
977+
check_method_receiver(wfcx, hir_sig, item, self_ty)
976978
}
977979
ty::AssocKind::Type => {
978980
if let ty::AssocItemContainer::TraitContainer = item.container {
@@ -983,6 +985,7 @@ fn check_associated_item(
983985
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
984986
wfcx.register_wf_obligation(span, loc, ty.into());
985987
}
988+
Ok(())
986989
}
987990
}
988991
})
@@ -1097,6 +1100,7 @@ fn check_type_defn<'tcx>(
10971100
}
10981101

10991102
check_where_clauses(wfcx, item.span, item.owner_id.def_id);
1103+
Ok(())
11001104
})
11011105
}
11021106

@@ -1121,7 +1125,8 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuarant
11211125
}
11221126

11231127
let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
1124-
check_where_clauses(wfcx, item.span, def_id)
1128+
check_where_clauses(wfcx, item.span, def_id);
1129+
Ok(())
11251130
});
11261131

11271132
// Only check traits, don't check trait aliases
@@ -1164,6 +1169,7 @@ fn check_item_fn(
11641169
enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
11651170
let sig = tcx.fn_sig(def_id).instantiate_identity();
11661171
check_fn_or_method(wfcx, ident.span, sig, decl, def_id);
1172+
Ok(())
11671173
})
11681174
}
11691175

@@ -1218,6 +1224,7 @@ fn check_item_type(
12181224
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
12191225
);
12201226
}
1227+
Ok(())
12211228
})
12221229
}
12231230

@@ -1276,6 +1283,7 @@ fn check_impl<'tcx>(
12761283
}
12771284

12781285
check_where_clauses(wfcx, item.span, item.owner_id.def_id);
1286+
Ok(())
12791287
})
12801288
}
12811289

@@ -1548,11 +1556,11 @@ fn check_method_receiver<'tcx>(
15481556
fn_sig: &hir::FnSig<'_>,
15491557
method: ty::AssocItem,
15501558
self_ty: Ty<'tcx>,
1551-
) {
1559+
) -> Result<(), ErrorGuaranteed> {
15521560
let tcx = wfcx.tcx();
15531561

15541562
if !method.fn_has_self_parameter {
1555-
return;
1563+
return Ok(());
15561564
}
15571565

15581566
let span = fn_sig.decl.inputs[0].span;
@@ -1571,11 +1579,11 @@ fn check_method_receiver<'tcx>(
15711579
if tcx.features().arbitrary_self_types {
15721580
if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
15731581
// Report error; `arbitrary_self_types` was enabled.
1574-
e0307(tcx, span, receiver_ty);
1582+
return Err(e0307(tcx, span, receiver_ty));
15751583
}
15761584
} else {
15771585
if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, false) {
1578-
if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
1586+
return Err(if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
15791587
// Report error; would have worked with `arbitrary_self_types`.
15801588
feature_err(
15811589
&tcx.sess.parse_sess,
@@ -1587,16 +1595,17 @@ fn check_method_receiver<'tcx>(
15871595
),
15881596
)
15891597
.help(HELP_FOR_SELF_TYPE)
1590-
.emit();
1598+
.emit()
15911599
} else {
15921600
// Report error; would not have worked with `arbitrary_self_types`.
1593-
e0307(tcx, span, receiver_ty);
1594-
}
1601+
e0307(tcx, span, receiver_ty)
1602+
});
15951603
}
15961604
}
1605+
Ok(())
15971606
}
15981607

1599-
fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) {
1608+
fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) -> ErrorGuaranteed {
16001609
struct_span_err!(
16011610
tcx.sess.diagnostic(),
16021611
span,
@@ -1605,7 +1614,7 @@ fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) {
16051614
)
16061615
.note("type of `self` must be `Self` or a type that dereferences to it")
16071616
.help(HELP_FOR_SELF_TYPE)
1608-
.emit();
1617+
.emit()
16091618
}
16101619

16111620
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature
2+
--> $DIR/arbitrary-self-from-method-substs.rs:8:43
3+
|
4+
LL | fn get<R: Deref<Target = Self>>(self: R) -> u32 {
5+
| ^
6+
|
7+
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
8+
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
9+
= 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`)
10+
11+
error: aborting due to previous error
12+
13+
For more information about this error, try `rustc --explain E0658`.

tests/ui/self/arbitrary-self-from-method-substs.stderr tests/ui/self/arbitrary-self-from-method-substs.feature.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0308]: mismatched types
2-
--> $DIR/arbitrary-self-from-method-substs.rs:14:5
2+
--> $DIR/arbitrary-self-from-method-substs.rs:16:5
33
|
44
LL | foo.get::<&Foo>();
55
| ^^^ expected `&Foo`, found `Foo`
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
#![feature(arbitrary_self_types)]
1+
// revisions: default feature
2+
#![cfg_attr(feature, feature(arbitrary_self_types))]
23

34
use std::ops::Deref;
45

56
struct Foo(u32);
67
impl Foo {
7-
fn get<R: Deref<Target=Self>>(self: R) -> u32 {
8+
fn get<R: Deref<Target = Self>>(self: R) -> u32 {
9+
//[default]~^ ERROR: `R` cannot be used as the type of `self`
810
self.0
911
}
1012
}
1113

1214
fn main() {
1315
let mut foo = Foo(1);
1416
foo.get::<&Foo>();
15-
//~^ ERROR mismatched types
17+
//[feature]~^ ERROR mismatched types
1618
}

0 commit comments

Comments
 (0)