Change inference var check to be in project_type
This commit is contained in:
parent
3602e0e262
commit
7ad48bd4e2
7 changed files with 27 additions and 32 deletions
|
@ -2470,7 +2470,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
let projection_ty = ty::ProjectionTy {
|
let projection_ty = ty::ProjectionTy {
|
||||||
// `T`
|
// `T`
|
||||||
substs: self.tcx.mk_substs_trait(
|
substs: self.tcx.mk_substs_trait(
|
||||||
trait_ref.self_ty().skip_binder(),
|
trait_pred.self_ty().skip_binder(),
|
||||||
&self.fresh_substs_for_item(span, item_def_id)[1..],
|
&self.fresh_substs_for_item(span, item_def_id)[1..],
|
||||||
),
|
),
|
||||||
// `Future::Output`
|
// `Future::Output`
|
||||||
|
|
|
@ -1073,6 +1073,16 @@ fn project<'cx, 'tcx>(
|
||||||
return Ok(Projected::Progress(Progress::error(selcx.tcx())));
|
return Ok(Projected::Progress(Progress::error(selcx.tcx())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the obligation contains any inference types or consts in associated
|
||||||
|
// type substs, then we don't assemble any candidates.
|
||||||
|
// This isn't really correct, but otherwise we can end up in a case where
|
||||||
|
// we constrain inference variables by selecting a single predicate, when
|
||||||
|
// we need to stay general. See issue #91762.
|
||||||
|
let (_, predicate_own_substs) = obligation.predicate.trait_ref_and_own_substs(selcx.tcx());
|
||||||
|
if predicate_own_substs.iter().any(|g| g.has_infer_types_or_consts()) {
|
||||||
|
return Err(ProjectionError::TooManyCandidates);
|
||||||
|
}
|
||||||
|
|
||||||
let mut candidates = ProjectionCandidateSet::None;
|
let mut candidates = ProjectionCandidateSet::None;
|
||||||
|
|
||||||
// Make sure that the following procedures are kept in order. ParamEnv
|
// Make sure that the following procedures are kept in order. ParamEnv
|
||||||
|
|
|
@ -1521,16 +1521,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
infer_predicate.projection_ty
|
infer_predicate.projection_ty
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the obligation contains any inference types or consts in associated
|
|
||||||
// type substs, then we don't match any projection candidates against it.
|
|
||||||
// This isn't really correct, but otherwise we can end up in a case where
|
|
||||||
// we constrain inference variables by selecting a single predicate, when
|
|
||||||
// we need to stay general. See issue #91762.
|
|
||||||
let (_, predicate_own_substs) =
|
|
||||||
obligation.predicate.trait_ref_and_own_substs(self.infcx.tcx);
|
|
||||||
if predicate_own_substs.iter().any(|g| g.has_infer_types_or_consts()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
self.infcx
|
self.infcx
|
||||||
.at(&obligation.cause, obligation.param_env)
|
.at(&obligation.cause, obligation.param_env)
|
||||||
.sup(obligation.predicate, infer_projection)
|
.sup(obligation.predicate, infer_projection)
|
||||||
|
|
|
@ -17,6 +17,7 @@ impl<T> UnsafeCopy for T {}
|
||||||
fn main() {
|
fn main() {
|
||||||
let b = Box::new(42usize);
|
let b = Box::new(42usize);
|
||||||
let copy = <()>::copy(&b);
|
let copy = <()>::copy(&b);
|
||||||
|
//~^ type annotations needed
|
||||||
|
|
||||||
let raw_b = Box::deref(&b) as *const _;
|
let raw_b = Box::deref(&b) as *const _;
|
||||||
let raw_copy = Box::deref(©) as *const _;
|
let raw_copy = Box::deref(©) as *const _;
|
||||||
|
|
|
@ -27,6 +27,13 @@ help: consider restricting type parameter `T`
|
||||||
LL | type Copy<T: std::clone::Clone>: Copy = Box<T>;
|
LL | type Copy<T: std::clone::Clone>: Copy = Box<T>;
|
||||||
| +++++++++++++++++++
|
| +++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error[E0282]: type annotations needed
|
||||||
|
--> $DIR/issue-74824.rs:19:16
|
||||||
|
|
|
||||||
|
LL | let copy = <()>::copy(&b);
|
||||||
|
| ^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `copy`
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0277, E0282.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub trait FunctorExt<T>: Sized {
|
||||||
|
|
||||||
arg = self;
|
arg = self;
|
||||||
ret = <Self::Base as Functor>::fmap(arg);
|
ret = <Self::Base as Functor>::fmap(arg);
|
||||||
//~^ mismatched types
|
//~^ type annotations needed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,9 @@
|
||||||
error[E0308]: mismatched types
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/issue-91762.rs:25:45
|
--> $DIR/issue-91762.rs:25:15
|
||||||
|
|
|
|
||||||
LL | / pub trait FunctorExt<T>: Sized {
|
LL | ret = <Self::Base as Functor>::fmap(arg);
|
||||||
LL | | type Base: Functor<With<T> = Self>;
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `fmap`
|
||||||
LL | |
|
|
||||||
LL | | fn fmap<U>(self) {
|
|
||||||
... |
|
|
||||||
LL | | ret = <Self::Base as Functor>::fmap(arg);
|
|
||||||
| | ^^^ expected associated type, found type parameter `Self`
|
|
||||||
LL | |
|
|
||||||
LL | | }
|
|
||||||
LL | | }
|
|
||||||
| |_- this type parameter
|
|
||||||
|
|
|
||||||
= note: expected associated type `<<Self as FunctorExt<T>>::Base as Functor>::With<_>`
|
|
||||||
found type parameter `Self`
|
|
||||||
= note: you might be missing a type parameter or trait bound
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
For more information about this error, try `rustc --explain E0282`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue