about summary refs log tree commit diff
diff options
context:
space:
mode:
author许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2023-02-09 00:49:43 +0800
committer许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2023-02-09 15:15:15 +0800
commitb58347a9c607e493ff947ff470492c38f7819c72 (patch)
treea2a90965a5dac72702ff4f1888dc837a5f56472d
parentb082e80e20475b1ec5b0bd0dd1dac3e6759c8022 (diff)
downloadrust-b58347a9c607e493ff947ff470492c38f7819c72.tar.gz
rust-b58347a9c607e493ff947ff470492c38f7819c72.zip
Don't expose type parameters and implementation details from macro expansion
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs23
-rw-r--r--tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs19
-rw-r--r--tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr11
-rw-r--r--tests/ui/issues/issue-16966.stderr6
-rw-r--r--tests/ui/parser/missing-closing-angle-bracket-eq-constraint.rs2
-rw-r--r--tests/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr12
-rw-r--r--tests/ui/type/type-check/cannot_infer_local_or_vec.stderr6
-rw-r--r--tests/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr6
8 files changed, 59 insertions, 26 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index b8c843a8a5a..c092efbb557 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -158,8 +158,12 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte
         if infcx.probe_ty_var(ty_vid).is_ok() {
             warn!("resolved ty var in error message");
         }
-        if let TypeVariableOriginKind::TypeParameterDefinition(name, _) =
-            infcx.inner.borrow_mut().type_variables().var_origin(ty_vid).kind
+
+        let mut infcx_inner = infcx.inner.borrow_mut();
+        let ty_vars = infcx_inner.type_variables();
+        let var_origin = ty_vars.var_origin(ty_vid);
+        if let TypeVariableOriginKind::TypeParameterDefinition(name, _) = var_origin.kind
+            && !var_origin.span.from_expansion()
         {
             Some(name)
         } else {
@@ -254,7 +258,7 @@ impl<'tcx> InferCtxt<'tcx> {
                     if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) =
                         var_origin.kind
                     {
-                        if name != kw::SelfUpper {
+                        if name != kw::SelfUpper && !var_origin.span.from_expansion() {
                             return InferenceDiagnosticsData {
                                 name: name.to_string(),
                                 span: Some(var_origin.span),
@@ -780,7 +784,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
         // The sources are listed in order of preference here.
         let tcx = self.infcx.tcx;
         let ctx = CostCtxt { tcx };
-        let base_cost = match source.kind {
+        match source.kind {
             InferSourceKind::LetBinding { ty, .. } => ctx.ty_cost(ty),
             InferSourceKind::ClosureArg { ty, .. } => ctx.ty_cost(ty),
             InferSourceKind::GenericArg { def_id, generic_args, .. } => {
@@ -797,17 +801,17 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
             InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => {
                 30 + ctx.ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 }
             }
-        };
-
-        let suggestion_may_apply = if source.from_expansion() { 10000 } else { 0 };
-
-        base_cost + suggestion_may_apply
+        }
     }
 
     /// Uses `fn source_cost` to determine whether this inference source is preferable to
     /// previous sources. We generally prefer earlier sources.
     #[instrument(level = "debug", skip(self))]
     fn update_infer_source(&mut self, mut new_source: InferSource<'tcx>) {
+        if new_source.from_expansion() {
+            return;
+        }
+
         let cost = self.source_cost(&new_source) + self.attempt;
         debug!(?cost);
         self.attempt += 1;
@@ -819,6 +823,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
             // `let x: _ = iter.collect();`, as this is a very common case.
             *def_id = Some(did);
         }
+
         if cost < self.infer_source_cost {
             self.infer_source_cost = cost;
             self.infer_source = Some(new_source);
diff --git a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs
new file mode 100644
index 00000000000..7f6758f47f8
--- /dev/null
+++ b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs
@@ -0,0 +1,19 @@
+// ignore-tidy-linelength
+
+// Regression test for #107745.
+// Previously need_type_info::update_infer_source will consider expressions originating from
+// macro expressions as candiate "previous sources". This unfortunately can mean that
+// for macros expansions such as `format!()` internal implementation details can leak, such as:
+//
+// ```
+// error[E0282]: type annotations needed
+// --> src/main.rs:2:22
+//  |
+//2 |     println!("{:?}", []);
+//  |                      ^^ cannot infer type of the type parameter `T` declared on the associated function `new_debug`
+// ```
+
+fn main() {
+    println!("{:?}", []);
+    //~^ ERROR type annotations needed
+}
diff --git a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr
new file mode 100644
index 00000000000..464655bbcf4
--- /dev/null
+++ b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr
@@ -0,0 +1,11 @@
+error[E0282]: type annotations needed
+  --> $DIR/issue-107745-avoid-expr-from-macro-expansion.rs:17:22
+   |
+LL |     println!("{:?}", []);
+   |                      ^^ cannot infer type
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/issues/issue-16966.stderr b/tests/ui/issues/issue-16966.stderr
index 60f5190dbd0..8c92505b5eb 100644
--- a/tests/ui/issues/issue-16966.stderr
+++ b/tests/ui/issues/issue-16966.stderr
@@ -1,10 +1,8 @@
 error[E0282]: type annotations needed
-  --> $DIR/issue-16966.rs:2:5
+  --> $DIR/issue-16966.rs:2:12
    |
 LL |     panic!(std::default::Default::default());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `M` declared on the function `begin_panic`
-   |
-   = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
 
 error: aborting due to previous error
 
diff --git a/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.rs b/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.rs
index da95c1bfa27..a56cd17773d 100644
--- a/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.rs
+++ b/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.rs
@@ -17,7 +17,7 @@ fn test2<T1, T2>(arg1 : T1, arg2 : T2) {
 fn test3<'a>(arg : &'a u32) {
   let v : Vec<'a = vec![];
     //~^ ERROR: expected one of
-    //~| ERROR: type annotations needed for `Vec<T>`
+    //~| ERROR: type annotations needed for `Vec<_>`
 }
 
 fn main() {}
diff --git a/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr b/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr
index bad241634cb..b2448774ae9 100644
--- a/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr
+++ b/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr
@@ -39,26 +39,26 @@ help: you might have meant to end the type parameters here
 LL |   let v : Vec<'a> = vec![];
    |                 +
 
-error[E0282]: type annotations needed for `Vec<T>`
+error[E0282]: type annotations needed for `Vec<_>`
   --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:7
    |
 LL |   let v : Vec<(u32,_) = vec![];
    |       ^
    |
-help: consider giving `v` an explicit type, where the type for type parameter `T` is specified
+help: consider giving `v` an explicit type, where the placeholders `_` are specified
    |
-LL |   let v: Vec<T> : Vec<(u32,_) = vec![];
+LL |   let v: Vec<_> : Vec<(u32,_) = vec![];
    |        ++++++++
 
-error[E0282]: type annotations needed for `Vec<T>`
+error[E0282]: type annotations needed for `Vec<_>`
   --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:7
    |
 LL |   let v : Vec<'a = vec![];
    |       ^
    |
-help: consider giving `v` an explicit type, where the type for type parameter `T` is specified
+help: consider giving `v` an explicit type, where the placeholders `_` are specified
    |
-LL |   let v: Vec<T> : Vec<'a = vec![];
+LL |   let v: Vec<_> : Vec<'a = vec![];
    |        ++++++++
 
 error: aborting due to 5 previous errors
diff --git a/tests/ui/type/type-check/cannot_infer_local_or_vec.stderr b/tests/ui/type/type-check/cannot_infer_local_or_vec.stderr
index b63d2a3b61c..09c4b2053b2 100644
--- a/tests/ui/type/type-check/cannot_infer_local_or_vec.stderr
+++ b/tests/ui/type/type-check/cannot_infer_local_or_vec.stderr
@@ -1,12 +1,12 @@
-error[E0282]: type annotations needed for `Vec<T>`
+error[E0282]: type annotations needed for `Vec<_>`
   --> $DIR/cannot_infer_local_or_vec.rs:2:9
    |
 LL |     let x = vec![];
    |         ^
    |
-help: consider giving `x` an explicit type, where the type for type parameter `T` is specified
+help: consider giving `x` an explicit type, where the placeholders `_` are specified
    |
-LL |     let x: Vec<T> = vec![];
+LL |     let x: Vec<_> = vec![];
    |          ++++++++
 
 error: aborting due to previous error
diff --git a/tests/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/tests/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr
index e544b369515..1fa253052e6 100644
--- a/tests/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr
+++ b/tests/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr
@@ -1,12 +1,12 @@
-error[E0282]: type annotations needed for `(Vec<T>,)`
+error[E0282]: type annotations needed for `(Vec<_>,)`
   --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:9
    |
 LL |     let (x, ) = (vec![], );
    |         ^^^^^   ---------- type must be known at this point
    |
-help: consider giving this pattern a type, where the type for type parameter `T` is specified
+help: consider giving this pattern a type, where the placeholders `_` are specified
    |
-LL |     let (x, ): (Vec<T>,) = (vec![], );
+LL |     let (x, ): (Vec<_>,) = (vec![], );
    |              +++++++++++
 
 error: aborting due to previous error