Skip to content

Commit

Permalink
Change inference var check to be in project_type
Browse files Browse the repository at this point in the history
  • Loading branch information
jackh726 committed Feb 7, 2022
1 parent 3602e0e commit 7ad48bd
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2470,7 +2470,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let projection_ty = ty::ProjectionTy {
// `T`
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..],
),
// `Future::Output`
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,16 @@ fn project<'cx, '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;

// Make sure that the following procedures are kept in order. ParamEnv
Expand Down
10 changes: 0 additions & 10 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1521,16 +1521,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
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
.at(&obligation.cause, obligation.param_env)
.sup(obligation.predicate, infer_projection)
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/generic-associated-types/issue-74824.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ impl<T> UnsafeCopy for T {}
fn main() {
let b = Box::new(42usize);
let copy = <()>::copy(&b);
//~^ type annotations needed

let raw_b = Box::deref(&b) as *const _;
let raw_copy = Box::deref(&copy) as *const _;
Expand Down
11 changes: 9 additions & 2 deletions src/test/ui/generic-associated-types/issue-74824.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ help: consider restricting type parameter `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`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
Some errors have detailed explanations: E0277, E0282.
For more information about an error, try `rustc --explain E0277`.
2 changes: 1 addition & 1 deletion src/test/ui/generic-associated-types/issue-91762.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub trait FunctorExt<T>: Sized {

arg = self;
ret = <Self::Base as Functor>::fmap(arg);
//~^ mismatched types
//~^ type annotations needed
}
}

Expand Down
23 changes: 5 additions & 18 deletions src/test/ui/generic-associated-types/issue-91762.stderr
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
error[E0308]: mismatched types
--> $DIR/issue-91762.rs:25:45
error[E0282]: type annotations needed
--> $DIR/issue-91762.rs:25:15
|
LL | / pub trait FunctorExt<T>: Sized {
LL | | type Base: Functor<With<T> = Self>;
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
LL | ret = <Self::Base as Functor>::fmap(arg);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `fmap`

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`.

0 comments on commit 7ad48bd

Please sign in to comment.