Don't expose type parameters and implementation details from macro expansion

This commit is contained in:
许杰友 Jieyou Xu (Joe) 2023-02-09 00:49:43 +08:00
parent b082e80e20
commit b58347a9c6
No known key found for this signature in database
GPG Key ID: C5FD5D32014FDB47
8 changed files with 59 additions and 26 deletions

View File

@ -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() { if infcx.probe_ty_var(ty_vid).is_ok() {
warn!("resolved ty var in error message"); 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) Some(name)
} else { } else {
@ -254,7 +258,7 @@ pub fn extract_inference_diagnostics_data(
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) =
var_origin.kind var_origin.kind
{ {
if name != kw::SelfUpper { if name != kw::SelfUpper && !var_origin.span.from_expansion() {
return InferenceDiagnosticsData { return InferenceDiagnosticsData {
name: name.to_string(), name: name.to_string(),
span: Some(var_origin.span), span: Some(var_origin.span),
@ -780,7 +784,7 @@ fn ty_cost(self, ty: Ty<'tcx>) -> usize {
// The sources are listed in order of preference here. // The sources are listed in order of preference here.
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let ctx = CostCtxt { tcx }; let ctx = CostCtxt { tcx };
let base_cost = match source.kind { match source.kind {
InferSourceKind::LetBinding { ty, .. } => ctx.ty_cost(ty), InferSourceKind::LetBinding { ty, .. } => ctx.ty_cost(ty),
InferSourceKind::ClosureArg { ty, .. } => ctx.ty_cost(ty), InferSourceKind::ClosureArg { ty, .. } => ctx.ty_cost(ty),
InferSourceKind::GenericArg { def_id, generic_args, .. } => { InferSourceKind::GenericArg { def_id, generic_args, .. } => {
@ -797,17 +801,17 @@ fn ty_cost(self, ty: Ty<'tcx>) -> usize {
InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => { InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => {
30 + ctx.ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 } 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 /// Uses `fn source_cost` to determine whether this inference source is preferable to
/// previous sources. We generally prefer earlier sources. /// previous sources. We generally prefer earlier sources.
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn update_infer_source(&mut self, mut new_source: InferSource<'tcx>) { 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; let cost = self.source_cost(&new_source) + self.attempt;
debug!(?cost); debug!(?cost);
self.attempt += 1; self.attempt += 1;
@ -819,6 +823,7 @@ fn update_infer_source(&mut self, mut new_source: InferSource<'tcx>) {
// `let x: _ = iter.collect();`, as this is a very common case. // `let x: _ = iter.collect();`, as this is a very common case.
*def_id = Some(did); *def_id = Some(did);
} }
if cost < self.infer_source_cost { if cost < self.infer_source_cost {
self.infer_source_cost = cost; self.infer_source_cost = cost;
self.infer_source = Some(new_source); self.infer_source = Some(new_source);

View File

@ -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
}

View File

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

View File

@ -1,10 +1,8 @@
error[E0282]: type annotations needed error[E0282]: type annotations needed
--> $DIR/issue-16966.rs:2:5 --> $DIR/issue-16966.rs:2:12
| |
LL | panic!(std::default::Default::default()); LL | panic!(std::default::Default::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `M` declared on the function `begin_panic` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
= 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)
error: aborting due to previous error error: aborting due to previous error

View File

@ -17,7 +17,7 @@ fn test2<T1, T2>(arg1 : T1, arg2 : T2) {
fn test3<'a>(arg : &'a u32) { fn test3<'a>(arg : &'a u32) {
let v : Vec<'a = vec![]; let v : Vec<'a = vec![];
//~^ ERROR: expected one of //~^ ERROR: expected one of
//~| ERROR: type annotations needed for `Vec<T>` //~| ERROR: type annotations needed for `Vec<_>`
} }
fn main() {} fn main() {}

View File

@ -39,26 +39,26 @@ help: you might have meant to end the type parameters here
LL | let v : Vec<'a> = vec![]; 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 --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:7
| |
LL | let v : Vec<(u32,_) = vec![]; 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 --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:7
| |
LL | let v : Vec<'a = vec![]; 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 error: aborting due to 5 previous errors

View File

@ -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 --> $DIR/cannot_infer_local_or_vec.rs:2:9
| |
LL | let x = vec![]; 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 error: aborting due to previous error

View File

@ -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 --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:9
| |
LL | let (x, ) = (vec![], ); LL | let (x, ) = (vec![], );
| ^^^^^ ---------- type must be known at this point | ^^^^^ ---------- 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 error: aborting due to previous error