fix ICE for deref coercions with type errors
This commit is contained in:
parent
b17491c8f6
commit
95c5b06000
@ -91,10 +91,6 @@ fn next(&mut self) -> Option<Self::Item> {
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
if new_ty.references_error() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.state.steps.push((self.state.cur_ty, kind));
|
self.state.steps.push((self.state.cur_ty, kind));
|
||||||
debug!(
|
debug!(
|
||||||
"autoderef stage #{:?} is {:?} from {:?}",
|
"autoderef stage #{:?} is {:?} from {:?}",
|
||||||
@ -137,6 +133,10 @@ fn overloaded_deref_ty(&mut self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
|
|||||||
debug!("overloaded_deref_ty({:?})", ty);
|
debug!("overloaded_deref_ty({:?})", ty);
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
|
|
||||||
|
if ty.references_error() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
// <ty as Deref>
|
// <ty as Deref>
|
||||||
let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]);
|
let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]);
|
||||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||||
|
@ -1635,6 +1635,12 @@ fn check_method_receiver<'tcx>(
|
|||||||
let receiver_ty = sig.inputs()[0];
|
let receiver_ty = sig.inputs()[0];
|
||||||
let receiver_ty = wfcx.normalize(span, None, receiver_ty);
|
let receiver_ty = wfcx.normalize(span, None, receiver_ty);
|
||||||
|
|
||||||
|
// If the receiver already has errors reported, consider it valid to avoid
|
||||||
|
// unnecessary errors (#58712).
|
||||||
|
if receiver_ty.references_error() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
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.
|
||||||
@ -1749,9 +1755,7 @@ fn receiver_is_valid<'tcx>(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
|
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
|
||||||
// If the receiver already has errors reported due to it, consider it valid to avoid
|
return false;
|
||||||
// unnecessary errors (#58712).
|
|
||||||
return receiver_ty.references_error();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,26 @@
|
|||||||
// Regression test for an ICE: https://github.com/rust-lang/rust/issues/120884
|
// Test that we don't ICE for coercions with type errors.
|
||||||
// We still need to properly go through coercions between types with errors instead of
|
// We still need to properly go through coercions between types with errors instead of
|
||||||
// shortcutting and returning success, because we need the adjustments for building the MIR.
|
// shortcutting and returning success, because we need the adjustments for building the MIR.
|
||||||
|
|
||||||
pub fn has_error() -> TypeError {}
|
pub fn has_error() -> TypeError {}
|
||||||
//~^ ERROR cannot find type `TypeError` in this scope
|
//~^ ERROR cannot find type `TypeError` in this scope
|
||||||
|
|
||||||
pub fn cast() -> *const u8 {
|
// https://github.com/rust-lang/rust/issues/120884
|
||||||
// Casting a function item to a data pointer in valid in HIR, but invalid in MIR.
|
// Casting a function item to a data pointer in valid in HIR, but invalid in MIR.
|
||||||
// We need an adjustment (ReifyFnPointer) to insert a cast from the function item
|
// We need an adjustment (ReifyFnPointer) to insert a cast from the function item
|
||||||
// to a function pointer as a separate MIR statement.
|
// to a function pointer as a separate MIR statement.
|
||||||
|
pub fn cast() -> *const u8 {
|
||||||
has_error as *const u8
|
has_error as *const u8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/rust-lang/rust/issues/120945
|
||||||
|
// This one ICEd, because we skipped the builtin deref from `&TypeError` to `TypeError`.
|
||||||
|
pub fn autoderef_source(e: &TypeError) {
|
||||||
|
//~^ ERROR cannot find type `TypeError` in this scope
|
||||||
|
autoderef_target(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn autoderef_target(_: &TypeError) {}
|
||||||
|
//~^ ERROR cannot find type `TypeError` in this scope
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -4,6 +4,18 @@ error[E0412]: cannot find type `TypeError` in this scope
|
|||||||
LL | pub fn has_error() -> TypeError {}
|
LL | pub fn has_error() -> TypeError {}
|
||||||
| ^^^^^^^^^ not found in this scope
|
| ^^^^^^^^^ not found in this scope
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error[E0412]: cannot find type `TypeError` in this scope
|
||||||
|
--> $DIR/type-errors.rs:18:29
|
||||||
|
|
|
||||||
|
LL | pub fn autoderef_source(e: &TypeError) {
|
||||||
|
| ^^^^^^^^^ not found in this scope
|
||||||
|
|
||||||
|
error[E0412]: cannot find type `TypeError` in this scope
|
||||||
|
--> $DIR/type-errors.rs:23:29
|
||||||
|
|
|
||||||
|
LL | pub fn autoderef_target(_: &TypeError) {}
|
||||||
|
| ^^^^^^^^^ not found in this scope
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0412`.
|
For more information about this error, try `rustc --explain E0412`.
|
||||||
|
Loading…
Reference in New Issue
Block a user