about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2023-02-17 18:42:47 +0100
committerLeón Orell Valerian Liehr <me@fmease.dev>2023-02-19 18:35:35 +0100
commit77ea90ec71926df7d478834d34d1fefce40cc456 (patch)
tree31795f434ac3b85765e696bf6202d0a574f00411
parent6065867a7e4379a12e495912a41318f871104270 (diff)
downloadrust-77ea90ec71926df7d478834d34d1fefce40cc456.tar.gz
rust-77ea90ec71926df7d478834d34d1fefce40cc456.zip
Fix substitution bug
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs19
-rw-r--r--tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs2
-rw-r--r--tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr2
-rw-r--r--tests/ui/associated-inherent-types/substitute-params-bad.rs23
-rw-r--r--tests/ui/associated-inherent-types/substitute-params-bad.stderr20
-rw-r--r--tests/ui/associated-inherent-types/substitute-params.rs (renamed from tests/ui/associated-inherent-types/struct-generics.rs)8
7 files changed, 67 insertions, 19 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index f3a03805a44..b039e654fd0 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -225,7 +225,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     pub(crate) fn complain_about_ambiguous_inherent_assoc_type(
         &self,
         name: Ident,
-        candidates: Vec<(DefId, DefId)>,
+        candidates: Vec<DefId>,
         span: Span,
     ) -> ErrorGuaranteed {
         let mut err = struct_span_err!(
@@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     fn note_ambiguous_inherent_assoc_type(
         &self,
         err: &mut Diagnostic,
-        candidates: Vec<(DefId, DefId)>,
+        candidates: Vec<DefId>,
         span: Span,
     ) {
         let tcx = self.tcx();
@@ -251,11 +251,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         // Dynamic limit to avoid hiding just one candidate, which is silly.
         let limit = if candidates.len() == 5 { 5 } else { 4 };
 
-        for (index, &(assoc_item, _)) in candidates.iter().take(limit).enumerate() {
-            let impl_ = tcx.impl_of_method(assoc_item).unwrap();
+        for (index, &item) in candidates.iter().take(limit).enumerate() {
+            let impl_ = tcx.impl_of_method(item).unwrap();
 
-            let note_span = if assoc_item.is_local() {
-                Some(tcx.def_span(assoc_item))
+            let note_span = if item.is_local() {
+                Some(tcx.def_span(item))
             } else if impl_.is_local() {
                 Some(tcx.def_span(impl_))
             } else {
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index c22ebc1c659..f43b92254eb 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -2267,7 +2267,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         return None;
                     }
 
-                    Some((assoc_item, def_scope))
+                    // FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot.
+                    Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs)))
                 })
             })
             .collect();
@@ -2275,23 +2276,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         if applicable_candidates.len() > 1 {
             return Err(self.complain_about_ambiguous_inherent_assoc_type(
                 name,
-                applicable_candidates,
+                applicable_candidates.into_iter().map(|(candidate, ..)| candidate).collect(),
                 span,
             ));
         }
 
-        if let Some((assoc_item, def_scope)) = applicable_candidates.pop() {
+        if let Some((assoc_item, def_scope, impl_substs)) = applicable_candidates.pop() {
             self.check_assoc_ty(assoc_item, name, def_scope, block, span);
 
-            let ty::Adt(_, adt_substs) = self_ty.kind() else {
-                bug!("unreachable: `lookup_inherent_assoc_ty` is only called on ADTs");
-            };
+            // FIXME(inherent_associated_types): To fully *confirm* the *probed* candidate,
+            // we still need to register region obligations for regionck to prove/disprove.
 
-            let item_substs = self.create_substs_for_associated_item(
-                span, assoc_item, segment,
-                // FIXME(fmease, #107468, #105305): Don't use `adt_substs` here but `impl_substs`.
-                adt_substs,
-            );
+            let item_substs =
+                self.create_substs_for_associated_item(span, assoc_item, segment, impl_substs);
 
             // FIXME(fmease, #106722): Check if the bounds on the parameters of the
             // associated type hold, if any.
diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs
index f10386bd9f9..f846bfa4168 100644
--- a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs
+++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs
@@ -31,7 +31,7 @@ fn main() {
     let _: Select<u8>::Projection = ();
 
     let _: Choose<NonCopy>::Result = ();
-    let _: Choose<&str>::Result = vec!["..."];
+    let _: Choose<bool>::Result = vec![true];
 }
 
 // Test if we use the correct `ParamEnv` when proving obligations.
diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr
index 1c77688b45a..c9a48872af4 100644
--- a/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr
+++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr
@@ -10,7 +10,7 @@ error[E0308]: mismatched types
   --> $DIR/dispatch-on-self-type-2.rs:16:47
    |
 LL |     let _: Parameterized<bool, u32>::Result = ();
-   |            --------------------------------   ^^ expected `bool`, found `()`
+   |            --------------------------------   ^^ expected `u32`, found `()`
    |            |
    |            expected due to this
 
diff --git a/tests/ui/associated-inherent-types/substitute-params-bad.rs b/tests/ui/associated-inherent-types/substitute-params-bad.rs
new file mode 100644
index 00000000000..00eb1a14da4
--- /dev/null
+++ b/tests/ui/associated-inherent-types/substitute-params-bad.rs
@@ -0,0 +1,23 @@
+// Regression test for issue #105305 and for
+// https://github.com/rust-lang/rust/issues/107468#issuecomment-1409096700
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<T>(T);
+
+impl<T, 'a> S<T> { //~ ERROR lifetime parameters must be declared prior to type and const parameters
+    type P = T;
+}
+
+struct Subj<T>(T);
+
+impl<T, S> Subj<(T, S)> {
+    type Un = (T, S);
+}
+
+fn main() {
+    type A = S<()>::P;
+
+    let _: Subj<(i32, i32)>::Un = 0i32; //~ ERROR mismatched types
+}
diff --git a/tests/ui/associated-inherent-types/substitute-params-bad.stderr b/tests/ui/associated-inherent-types/substitute-params-bad.stderr
new file mode 100644
index 00000000000..7a7808ba67b
--- /dev/null
+++ b/tests/ui/associated-inherent-types/substitute-params-bad.stderr
@@ -0,0 +1,20 @@
+error: lifetime parameters must be declared prior to type and const parameters
+  --> $DIR/substitute-params-bad.rs:9:9
+   |
+LL | impl<T, 'a> S<T> {
+   |     ----^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T>`
+
+error[E0308]: mismatched types
+  --> $DIR/substitute-params-bad.rs:22:35
+   |
+LL |     let _: Subj<(i32, i32)>::Un = 0i32;
+   |            --------------------   ^^^^ expected `(i32, i32)`, found `i32`
+   |            |
+   |            expected due to this
+   |
+   = note: expected tuple `(i32, i32)`
+               found type `i32`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-inherent-types/struct-generics.rs b/tests/ui/associated-inherent-types/substitute-params.rs
index 8952b379173..e94d6833159 100644
--- a/tests/ui/associated-inherent-types/struct-generics.rs
+++ b/tests/ui/associated-inherent-types/substitute-params.rs
@@ -9,7 +9,15 @@ impl<T> S<T> {
     type P = T;
 }
 
+impl<T> S<(T,)> {
+    type Un = T;
+}
+
 fn main() {
+    // Regression test for issue #104240.
     type A = S<()>::P;
     let _: A = ();
+
+    // Regression test for issue #107468.
+    let _: S<(i32,)>::Un = 0i32;
 }