diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-02-08 16:40:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-08 16:40:48 +0100 |
| commit | a11e2b1f755e392e7c776b98e76aa86a30b7b22e (patch) | |
| tree | b332e296015c8868de7e32f74c4417dbcee92619 | |
| parent | 8429dcdb79b35182036e8de574287a7acc4b14d8 (diff) | |
| parent | 7ad48bd4e22aaffa5ac32809b9196fab9c04de2c (diff) | |
| download | rust-a11e2b1f755e392e7c776b98e76aa86a30b7b22e.tar.gz rust-a11e2b1f755e392e7c776b98e76aa86a30b7b22e.zip | |
Rollup merge of #92917 - jackh726:issue-91762-2, r=nikomatsakis
Don't constrain projection predicates with inference vars in GAT substs cc #91762 Not a fix, but a mitigation to prevent a backwards-compatible hazard where we normalize using a predicate only because it's the only one available, but shouldn't. This would constrain an inference variable which didn't really want. We already do this when selecting a projection candidate, which isn't always correct. But changing that is a problem for a different day. Also found out that a suggestion for `await`ing a future was using the wrong substs. r? ``@nikomatsakis``
6 files changed, 60 insertions, 3 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 51b8c9aca78..65a18897b39 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2473,7 +2473,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // `T` substs: self.tcx.mk_substs_trait( trait_pred.self_ty().skip_binder(), - self.fresh_substs_for_item(span, item_def_id), + &self.fresh_substs_for_item(span, item_def_id)[1..], ), // `Future::Output` item_def_id, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 5e7d4c8b415..36cc14610cb 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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 diff --git a/src/test/ui/generic-associated-types/issue-74824.rs b/src/test/ui/generic-associated-types/issue-74824.rs index 1bbf7aac5cd..01f99fa4487 100644 --- a/src/test/ui/generic-associated-types/issue-74824.rs +++ b/src/test/ui/generic-associated-types/issue-74824.rs @@ -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(©) as *const _; diff --git a/src/test/ui/generic-associated-types/issue-74824.stderr b/src/test/ui/generic-associated-types/issue-74824.stderr index 8517eb9fa21..e7ebf5964ba 100644 --- a/src/test/ui/generic-associated-types/issue-74824.stderr +++ b/src/test/ui/generic-associated-types/issue-74824.stderr @@ -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`. diff --git a/src/test/ui/generic-associated-types/issue-91762.rs b/src/test/ui/generic-associated-types/issue-91762.rs new file mode 100644 index 00000000000..b259a3c6e06 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-91762.rs @@ -0,0 +1,30 @@ +// check-fail + +// FIXME(generic_associated_types): We almost certaintly want this to pass, but +// it's particularly difficult currently, because we need a way of specifying +// that `<Self::Base as Functor>::With<T> = Self` without using that when we have +// a `U`. See `https://github.com/rust-lang/rust/pull/92728` for a (hacky) +// solution. This might be better to just wait for Chalk. + +#![feature(generic_associated_types)] + +pub trait Functor { + type With<T>; + + fn fmap<T, U>(this: Self::With<T>) -> Self::With<U>; +} + +pub trait FunctorExt<T>: Sized { + type Base: Functor<With<T> = Self>; + + fn fmap<U>(self) { + let arg: <Self::Base as Functor>::With<T>; + let ret: <Self::Base as Functor>::With<U>; + + arg = self; + ret = <Self::Base as Functor>::fmap(arg); + //~^ type annotations needed + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-91762.stderr b/src/test/ui/generic-associated-types/issue-91762.stderr new file mode 100644 index 00000000000..a9c465cdd7e --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-91762.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/issue-91762.rs:25:15 + | +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 E0282`. |
