Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #106758

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ad79b20
std tests: use __OsLocalKeyInner from realstd
RalfJung Jan 9, 2023
1a99361
Revert "warn newer available version of the x tool"
DebugSteven Jan 11, 2023
0d834d9
keep --wrapper-version argument in x
DebugSteven Jan 11, 2023
4e30ad8
Reuse ErrorGuaranteed during relation
compiler-errors Dec 30, 2022
83fbc71
Filter impl and where-clause candidates that reference errors
compiler-errors Jan 1, 2023
24bb36e
Consolidate two almost duplicated fn info extraction routines
compiler-errors Dec 27, 2022
2024aa4
Make `&`-removal suggestion verbose
estebank Jan 2, 2023
ce83be4
Account for type params
estebank Jan 2, 2023
bb72117
fix rebase
estebank Jan 7, 2023
8b8cce1
Use the root trait predicate to determine whether to remove references
estebank Jan 9, 2023
48b7e2a
Stabilize `::{core,std}::pin::pin!`
danielhenrymantilla Oct 31, 2022
621d412
Fix invalid syntax in impl Trait parameter type suggestions for E0311
Dec 26, 2022
8fa79a1
Rollup merge of #103800 - danielhenrymantilla:stabilize-pin-macro, r=…
Dylan-DPC Jan 12, 2023
989503e
Rollup merge of #106167 - yanchen4791:issue-105544-fix, r=oli-obk
Dylan-DPC Jan 12, 2023
c09bd57
Rollup merge of #106171 - compiler-errors:consolidate-extract_callabl…
Dylan-DPC Jan 12, 2023
11e4a4f
Rollup merge of #106309 - compiler-errors:prefer-non-err-candidates, …
Dylan-DPC Jan 12, 2023
22001ef
Rollup merge of #106360 - estebank:remove-borrow-suggestion, r=compil…
Dylan-DPC Jan 12, 2023
40ccb98
Rollup merge of #106638 - RalfJung:realstd, r=thomcc
Dylan-DPC Jan 12, 2023
1c9e2d4
Rollup merge of #106733 - DebugSteven:revert-104552-warn-newer-x, r=j…
Dylan-DPC Jan 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5034,18 +5034,18 @@ checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af"

[[package]]
name = "semver"
version = "1.0.14"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
dependencies = [
"serde",
]

[[package]]
name = "serde"
version = "1.0.152"
version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
dependencies = [
"serde_derive",
]
Expand All @@ -5062,9 +5062,9 @@ dependencies = [

[[package]]
name = "serde_derive"
version = "1.0.152"
version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
dependencies = [
"proc-macro2",
"quote",
Expand All @@ -5082,9 +5082,9 @@ dependencies = [

[[package]]
name = "serde_json"
version = "1.0.91"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
dependencies = [
"indexmap",
"itoa",
Expand Down Expand Up @@ -5400,9 +5400,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"

[[package]]
name = "syn"
version = "1.0.107"
version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
dependencies = [
"proc-macro2",
"quote",
Expand Down Expand Up @@ -5576,7 +5576,6 @@ dependencies = [
"lazy_static",
"miropt-test-tools",
"regex",
"semver",
"termcolor",
"walkdir",
]
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,8 +659,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};

if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) {
if let Some((maybe_def, output_ty, _)) =
self.extract_callable_info(callee_expr, callee_ty)
if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_ty)
&& !self.type_is_sized_modulo_regions(self.param_env, output_ty, callee_expr.span)
{
let descr = match maybe_def {
Expand Down
103 changes: 6 additions & 97 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use rustc_hir::{
Expr, ExprKind, GenericBound, Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
};
use rustc_hir_analysis::astconv::AstConv;
use rustc_infer::infer;
use rustc_infer::traits::{self, StatementAsExpression};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{
Expand All @@ -23,9 +22,9 @@ use rustc_span::source_map::Spanned;
use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
use rustc_trait_selection::traits::error_reporting::DefIdOrName;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::NormalizeExt;

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn body_fn_sig(&self) -> Option<ty::FnSig<'tcx>> {
Expand Down Expand Up @@ -94,7 +93,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
found: Ty<'tcx>,
can_satisfy: impl FnOnce(Ty<'tcx>) -> bool,
) -> bool {
let Some((def_id_or_name, output, inputs)) = self.extract_callable_info(expr, found)
let Some((def_id_or_name, output, inputs)) = self.extract_callable_info(found)
else { return false; };
if can_satisfy(output) {
let (sugg_call, mut applicability) = match inputs.len() {
Expand Down Expand Up @@ -163,99 +162,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// because the callable type must also be well-formed to be called.
pub(in super::super) fn extract_callable_info(
&self,
expr: &Expr<'_>,
found: Ty<'tcx>,
ty: Ty<'tcx>,
) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)> {
// Autoderef is useful here because sometimes we box callables, etc.
let Some((def_id_or_name, output, inputs)) = self.autoderef(expr.span, found).silence_errors().find_map(|(found, _)| {
match *found.kind() {
ty::FnPtr(fn_sig) =>
Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs())),
ty::FnDef(def_id, _) => {
let fn_sig = found.fn_sig(self.tcx);
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
}
ty::Closure(def_id, substs) => {
let fn_sig = substs.as_closure().sig();
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().map_bound(|inputs| &inputs[1..])))
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
&& Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
// args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
{
Some((
DefIdOrName::DefId(def_id),
pred.kind().rebind(proj.term.ty().unwrap()),
pred.kind().rebind(args.as_slice()),
))
} else {
None
}
})
}
ty::Dynamic(data, _, ty::Dyn) => {
data.iter().find_map(|pred| {
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
&& Some(proj.def_id) == self.tcx.lang_items().fn_once_output()
// for existential projection, substs are shifted over by 1
&& let ty::Tuple(args) = proj.substs.type_at(0).kind()
{
Some((
DefIdOrName::Name("trait object"),
pred.rebind(proj.term.ty().unwrap()),
pred.rebind(args.as_slice()),
))
} else {
None
}
})
}
ty::Param(param) => {
let def_id = self.tcx.generics_of(self.body_id.owner).type_param(&param, self.tcx).def_id;
self.tcx.predicates_of(self.body_id.owner).predicates.iter().find_map(|(pred, _)| {
if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
&& Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
&& proj.projection_ty.self_ty() == found
// args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
{
Some((
DefIdOrName::DefId(def_id),
pred.kind().rebind(proj.term.ty().unwrap()),
pred.kind().rebind(args.as_slice()),
))
} else {
None
}
})
}
_ => None,
}
}) else { return None; };

let output = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, output);
let inputs = inputs
.skip_binder()
.iter()
.map(|ty| {
self.replace_bound_vars_with_fresh_vars(
expr.span,
infer::FnCall,
inputs.rebind(*ty),
)
})
.collect();

// We don't want to register any extra obligations, which should be
// implied by wf, but also because that would possibly result in
// erroneous errors later on.
let infer::InferOk { value: output, obligations: _ } =
self.at(&self.misc(expr.span), self.param_env).normalize(output);

if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) }
self.err_ctxt().extract_callable_info(self.body_id, self.param_env, ty)
}

pub fn suggest_two_fn_call(
Expand All @@ -267,9 +176,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_ty: Ty<'tcx>,
can_satisfy: impl FnOnce(Ty<'tcx>, Ty<'tcx>) -> bool,
) -> bool {
let Some((_, lhs_output_ty, lhs_inputs)) = self.extract_callable_info(lhs_expr, lhs_ty)
let Some((_, lhs_output_ty, lhs_inputs)) = self.extract_callable_info(lhs_ty)
else { return false; };
let Some((_, rhs_output_ty, rhs_inputs)) = self.extract_callable_info(rhs_expr, rhs_ty)
let Some((_, rhs_output_ty, rhs_inputs)) = self.extract_callable_info(rhs_ty)
else { return false; };

if can_satisfy(lhs_output_ty, rhs_output_ty) {
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2655,8 +2655,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
found: Ty<'tcx>,
expected: Ty<'tcx>,
) -> bool {
let Some((_def_id_or_name, output, _inputs)) = self.extract_callable_info(expr, found)
else { return false; };
let Some((_def_id_or_name, output, _inputs)) =
self.extract_callable_info(found) else {
return false;
};

if !self.can_coerce(output, expected) {
return false;
Expand Down
94 changes: 77 additions & 17 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2144,18 +2144,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// suggest adding an explicit lifetime bound to it.
let generics = self.tcx.generics_of(generic_param_scope);
// type_param_span is (span, has_bounds)
let mut is_synthetic = false;
let mut ast_generics = None;
let type_param_span = match bound_kind {
GenericKind::Param(ref param) => {
// Account for the case where `param` corresponds to `Self`,
// which doesn't have the expected type argument.
if !(generics.has_self && param.index == 0) {
let type_param = generics.type_param(param, self.tcx);
is_synthetic = type_param.kind.is_synthetic();
type_param.def_id.as_local().map(|def_id| {
// Get the `hir::Param` to verify whether it already has any bounds.
// We do this to avoid suggesting code that ends up as `T: 'a'b`,
// instead we suggest `T: 'a + 'b` in that case.
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
let ast_generics = self.tcx.hir().get_generics(hir_id.owner.def_id);
ast_generics = self.tcx.hir().get_generics(hir_id.owner.def_id);
let bounds =
ast_generics.and_then(|g| g.bounds_span_for_suggestions(def_id));
// `sp` only covers `T`, change it so that it covers
Expand Down Expand Up @@ -2187,11 +2190,64 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
.unwrap_or("'lt".to_string())
};

let add_lt_sugg = generics
.params
.first()
.and_then(|param| param.def_id.as_local())
.map(|def_id| (self.tcx.def_span(def_id).shrink_to_lo(), format!("{}, ", new_lt)));
let mut add_lt_suggs: Vec<Option<_>> = vec![];
if is_synthetic {
if let Some(ast_generics) = ast_generics {
let named_lifetime_param_exist = ast_generics.params.iter().any(|p| {
matches!(
p.kind,
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
)
});
if named_lifetime_param_exist && let [param, ..] = ast_generics.params
{
add_lt_suggs.push(Some((
self.tcx.def_span(param.def_id).shrink_to_lo(),
format!("{new_lt}, "),
)));
} else {
add_lt_suggs
.push(Some((ast_generics.span.shrink_to_hi(), format!("<{new_lt}>"))));
}
}
} else {
if let [param, ..] = &generics.params[..] && let Some(def_id) = param.def_id.as_local()
{
add_lt_suggs
.push(Some((self.tcx.def_span(def_id).shrink_to_lo(), format!("{new_lt}, "))));
}
}

if let Some(ast_generics) = ast_generics {
for p in ast_generics.params {
if p.is_elided_lifetime() {
if self
.tcx
.sess
.source_map()
.span_to_prev_source(p.span.shrink_to_hi())
.ok()
.map_or(false, |s| *s.as_bytes().last().unwrap() == b'&')
{
add_lt_suggs
.push(Some(
(
p.span.shrink_to_hi(),
if let Ok(snip) = self.tcx.sess.source_map().span_to_next_source(p.span)
&& snip.starts_with(' ')
{
format!("{new_lt}")
} else {
format!("{new_lt} ")
}
)
));
} else {
add_lt_suggs.push(Some((p.span.shrink_to_hi(), format!("<{new_lt}>"))));
}
}
}
}

let labeled_user_string = match bound_kind {
GenericKind::Param(ref p) => format!("the parameter type `{}`", p),
Expand All @@ -2215,20 +2271,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);
}

fn binding_suggestion<S: fmt::Display>(
fn binding_suggestion<'tcx, S: fmt::Display>(
err: &mut Diagnostic,
type_param_span: Option<(Span, bool)>,
bound_kind: GenericKind<'_>,
bound_kind: GenericKind<'tcx>,
sub: S,
add_lt_sugg: Option<(Span, String)>,
add_lt_suggs: Vec<Option<(Span, String)>>,
) {
let msg = "consider adding an explicit lifetime bound";
if let Some((sp, has_lifetimes)) = type_param_span {
let suggestion =
if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) };
let mut suggestions = vec![(sp, suggestion)];
if let Some(add_lt_sugg) = add_lt_sugg {
suggestions.push(add_lt_sugg);
for add_lt_sugg in add_lt_suggs {
if let Some(add_lt_sugg) = add_lt_sugg {
suggestions.push(add_lt_sugg);
}
}
err.multipart_suggestion_verbose(
format!("{msg}..."),
Expand All @@ -2252,9 +2310,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
};
let mut sugg =
vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))];
if let Some(lt) = add_lt_sugg.clone() {
sugg.push(lt);
sugg.rotate_right(1);
for add_lt_sugg in add_lt_suggs.clone() {
if let Some(lt) = add_lt_sugg {
sugg.push(lt);
sugg.rotate_right(1);
}
}
// `MaybeIncorrect` due to issue #41966.
err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
Expand Down Expand Up @@ -2358,7 +2418,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// for the bound is not suitable for suggestions when `-Zverbose` is set because it
// uses `Debug` output, so we handle it specially here so that suggestions are
// always correct.
binding_suggestion(&mut err, type_param_span, bound_kind, name, None);
binding_suggestion(&mut err, type_param_span, bound_kind, name, vec![]);
err
}

Expand All @@ -2371,7 +2431,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
"{} may not live long enough",
labeled_user_string
);
binding_suggestion(&mut err, type_param_span, bound_kind, "'static", None);
binding_suggestion(&mut err, type_param_span, bound_kind, "'static", vec![]);
err
}

Expand Down Expand Up @@ -2410,7 +2470,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
type_param_span,
bound_kind,
new_lt,
add_lt_sugg,
add_lt_suggs,
);
}
}
Expand Down
Loading