Avoid autoderef coercions leaking if they don't apply
This commit is contained in:
parent
187e6bacac
commit
6fc3d3aa4c
@ -259,6 +259,8 @@ impl<'a> InferenceContext<'a> {
|
||||
// details of coercion errors though, so I think it's useful to leave
|
||||
// the structure like it is.
|
||||
|
||||
let snapshot = self.table.snapshot();
|
||||
|
||||
let mut autoderef = Autoderef::new(&mut self.table, from_ty.clone());
|
||||
let mut first_error = None;
|
||||
let mut found = None;
|
||||
@ -315,6 +317,7 @@ impl<'a> InferenceContext<'a> {
|
||||
let InferOk { value: ty, goals } = match found {
|
||||
Some(d) => d,
|
||||
None => {
|
||||
self.table.rollback_to(snapshot);
|
||||
let err = first_error.expect("coerce_borrowed_pointer had no error");
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -242,6 +242,45 @@ fn test() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn coerce_autoderef_implication_1() {
|
||||
check_no_mismatches(
|
||||
r"
|
||||
//- minicore: deref
|
||||
struct Foo<T>;
|
||||
impl core::ops::Deref for Foo<u32> { type Target = (); }
|
||||
|
||||
fn takes_ref_foo<T>(x: &Foo<T>) {}
|
||||
fn test() {
|
||||
let foo = Foo;
|
||||
//^^^ type: Foo<{unknown}>
|
||||
takes_ref_foo(&foo);
|
||||
|
||||
let foo = Foo;
|
||||
//^^^ type: Foo<u32>
|
||||
let _: &() = &foo;
|
||||
}",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn coerce_autoderef_implication_2() {
|
||||
check(
|
||||
r"
|
||||
//- minicore: deref
|
||||
struct Foo<T>;
|
||||
impl core::ops::Deref for Foo<u32> { type Target = (); }
|
||||
|
||||
fn takes_ref_foo<T>(x: &Foo<T>) {}
|
||||
fn test() {
|
||||
let foo = Foo;
|
||||
//^^^ type: Foo<{unknown}>
|
||||
let _: &u32 = &Foo;
|
||||
//^^^^ expected &u32, got &Foo<{unknown}>
|
||||
}",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn closure_return_coerce() {
|
||||
check_no_mismatches(
|
||||
|
Loading…
x
Reference in New Issue
Block a user