about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs11
-rw-r--r--tests/ui/privacy/suggest-box-new.rs3
-rw-r--r--tests/ui/privacy/suggest-box-new.stderr32
-rw-r--r--tests/ui/privacy/suggest-new-projection-ice.rs19
-rw-r--r--tests/ui/privacy/suggest-new-projection-ice.stderr10
-rw-r--r--tests/ui/suggestions/multi-suggestion.ascii.stderr2
-rw-r--r--tests/ui/suggestions/multi-suggestion.unicode.stderr2
7 files changed, 69 insertions, 10 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index a652e08905a..7adbee7ff28 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -2585,12 +2585,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .filter(|item| item.is_fn() && !item.is_method())
                 .filter_map(|item| {
                     // Only assoc fns that return `Self`
-                    let fn_sig = self.tcx.fn_sig(item.def_id).skip_binder();
-                    let ret_ty = fn_sig.output();
-                    let ret_ty = self.tcx.normalize_erasing_late_bound_regions(
-                        self.typing_env(self.param_env),
-                        ret_ty,
-                    );
+                    let fn_sig = self
+                        .tcx
+                        .fn_sig(item.def_id)
+                        .instantiate(self.tcx, self.fresh_args_for_item(span, item.def_id));
+                    let ret_ty = self.tcx.instantiate_bound_regions_with_erased(fn_sig.output());
                     if !self.can_eq(self.param_env, ret_ty, adt_ty) {
                         return None;
                     }
diff --git a/tests/ui/privacy/suggest-box-new.rs b/tests/ui/privacy/suggest-box-new.rs
index 7125285fc77..ff585387020 100644
--- a/tests/ui/privacy/suggest-box-new.rs
+++ b/tests/ui/privacy/suggest-box-new.rs
@@ -16,4 +16,7 @@ fn main() {
     let _ = std::collections::HashMap {};
     //~^ ERROR cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields
     let _ = Box {}; //~ ERROR cannot construct `Box<_, _>` with struct literal syntax due to private fields
+
+    // test that we properly instantiate the parameter of `Box::<T>::new` with an inference variable
+    let _ = Box::<i32> {}; //~ ERROR cannot construct `Box<i32>` with struct literal syntax due to private fields
 }
diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr
index 2b48e9046bf..37b2989dcc1 100644
--- a/tests/ui/privacy/suggest-box-new.stderr
+++ b/tests/ui/privacy/suggest-box-new.stderr
@@ -118,13 +118,41 @@ LL +     let _ = Box::new_zeroed();
 LL -     let _ = Box {};
 LL +     let _ = Box::new_in(_, _);
    |
-   = and 12 other candidates
+   = and 13 other candidates
 help: consider using the `Default` trait
    |
 LL -     let _ = Box {};
 LL +     let _ = <Box as std::default::Default>::default();
    |
 
-error: aborting due to 4 previous errors
+error: cannot construct `Box<i32>` with struct literal syntax due to private fields
+  --> $DIR/suggest-box-new.rs:21:13
+   |
+LL |     let _ = Box::<i32> {};
+   |             ^^^^^^^^^^
+   |
+   = note: private fields `0` and `1` that were not provided
+help: you might have meant to use an associated function to build this type
+   |
+LL -     let _ = Box::<i32> {};
+LL +     let _ = Box::<i32>::new(_);
+   |
+LL -     let _ = Box::<i32> {};
+LL +     let _ = Box::<i32>::new_in(_, _);
+   |
+LL -     let _ = Box::<i32> {};
+LL +     let _ = Box::<i32>::into_inner(_);
+   |
+LL -     let _ = Box::<i32> {};
+LL +     let _ = Box::<i32>::write(_, _);
+   |
+   = and 4 other candidates
+help: consider using the `Default` trait
+   |
+LL -     let _ = Box::<i32> {};
+LL +     let _ = <Box::<i32> as std::default::Default>::default();
+   |
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0423`.
diff --git a/tests/ui/privacy/suggest-new-projection-ice.rs b/tests/ui/privacy/suggest-new-projection-ice.rs
new file mode 100644
index 00000000000..41ac27508e8
--- /dev/null
+++ b/tests/ui/privacy/suggest-new-projection-ice.rs
@@ -0,0 +1,19 @@
+//! Regression test for <https://github.com/rust-lang/rust/issues/146174>.
+//! Ensure that we don't ICE when an associated function returns an associated type.
+
+mod m {
+    pub trait Project {
+        type Assoc;
+    }
+    pub struct Foo {
+        _priv: (),
+    }
+    impl Foo {
+        fn new<T: Project>() -> T::Assoc {
+            todo!()
+        }
+    }
+}
+fn main() {
+    let _ = m::Foo {}; //~ ERROR: cannot construct `Foo`
+}
diff --git a/tests/ui/privacy/suggest-new-projection-ice.stderr b/tests/ui/privacy/suggest-new-projection-ice.stderr
new file mode 100644
index 00000000000..4700772096b
--- /dev/null
+++ b/tests/ui/privacy/suggest-new-projection-ice.stderr
@@ -0,0 +1,10 @@
+error: cannot construct `Foo` with struct literal syntax due to private fields
+  --> $DIR/suggest-new-projection-ice.rs:18:13
+   |
+LL |     let _ = m::Foo {};
+   |             ^^^^^^
+   |
+   = note: private field `_priv` that was not provided
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr
index 1744162e6ce..9c8867a1771 100644
--- a/tests/ui/suggestions/multi-suggestion.ascii.stderr
+++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr
@@ -118,7 +118,7 @@ LL +     let _ = Box::new_zeroed();
 LL -     let _ = Box {};
 LL +     let _ = Box::new_in(_, _);
    |
-   = and 12 other candidates
+   = and 13 other candidates
 help: consider using the `Default` trait
    |
 LL -     let _ = Box {};
diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr
index 4835c263f19..4fdab51493e 100644
--- a/tests/ui/suggestions/multi-suggestion.unicode.stderr
+++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr
@@ -118,7 +118,7 @@ LL +     let _ = Box::new_zeroed();
 LL -     let _ = Box {};
 LL +     let _ = Box::new_in(_, _);

-   ╰ and 12 other candidates
+   ╰ and 13 other candidates
 help: consider using the `Default` trait
    ╭╴
 LL -     let _ = Box {};