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 8 pull requests #110308

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
50a8097
suggest lifetime for closure parameter type when mismatch
skyzh Mar 13, 2023
7b2c698
better suggestion based on hir
skyzh Mar 18, 2023
c025483
use param instead of ty
skyzh Mar 18, 2023
1e95cdd
feat: implement basic suggest-tests tool
Ezrashaw Mar 1, 2023
65c9c79
remove obsolete test
TDecking Apr 10, 2023
171f541
don't uniquify regions when canonicalizing
lcnr Apr 11, 2023
43e6f99
remove issue-2718.rs test
lcnr Apr 11, 2023
a159dcd
fix: disable `x suggest` when using `build-metrics`
Ezrashaw Apr 12, 2023
722e078
Remove useless match.
nnethercote Apr 13, 2023
c18773a
Make `mk_bound_region` closure more generic.
nnethercote Apr 13, 2023
7407668
Add `tidy-alphabetical` to features in `core`
scottmcm Apr 13, 2023
cd868dc
Cover edge cases for {f32, f64}.hypot() docs
jmaargh Apr 13, 2023
dcc51f1
change usage of bound_impl_subject to impl_subject
kylematsuda Apr 13, 2023
e2f5a5a
make tcx.impl_subject return EarlyBinder, remove bound_impl_subject, …
kylematsuda Apr 13, 2023
8d5ee1a
make impl_subject more readable
kylematsuda Apr 13, 2023
7dbd2e2
Remove one use of `BrAnon(Some(_))`.
nnethercote Apr 13, 2023
f07c335
Remove another use of `BrAnon(Some(_))`.
nnethercote Apr 13, 2023
c68c6c3
Add test for uniquifying regions
compiler-errors Apr 14, 2023
b1c4662
Rollup merge of #105888 - skyzh:skyzh/suggest-lifetime-closure, r=com…
Dylan-DPC Apr 14, 2023
e94eeb0
Rollup merge of #106249 - Ezrashaw:suggest-test-tool, r=jyn514,albert…
Dylan-DPC Apr 14, 2023
69ab280
Rollup merge of #110158 - TDecking:obsolete_test, r=ChrisDenton
Dylan-DPC Apr 14, 2023
41b4980
Rollup merge of #110180 - lcnr:canonicalize, r=compiler-errors
Dylan-DPC Apr 14, 2023
219da44
Rollup merge of #110269 - scottmcm:sort-features, r=jyn514
Dylan-DPC Apr 14, 2023
ed44074
Rollup merge of #110276 - nnethercote:rm-BrAnon-Span, r=jackh726
Dylan-DPC Apr 14, 2023
fad785f
Rollup merge of #110298 - jmaargh:jmaargh/hypot-docs-edge-cases, r=th…
Dylan-DPC Apr 14, 2023
8f7b5fc
Rollup merge of #110299 - kylematsuda:earlybinder-impl-subject, r=com…
Dylan-DPC Apr 14, 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
13 changes: 11 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3451,9 +3451,9 @@ dependencies = [

[[package]]
name = "once_cell"
version = "1.16.0"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"

[[package]]
name = "opener"
Expand Down Expand Up @@ -6101,6 +6101,15 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"

[[package]]
name = "suggest-tests"
version = "0.1.0"
dependencies = [
"build_helper",
"glob",
"once_cell",
]

[[package]]
name = "syn"
version = "1.0.102"
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ members = [
"src/tools/lld-wrapper",
"src/tools/collect-license-metadata",
"src/tools/generate-copyright",
"src/tools/suggest-tests",
]

exclude = [
Expand Down
25 changes: 10 additions & 15 deletions compiler/rustc_hir_typeck/src/generator_interior/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,7 @@ pub fn resolve_interior<'a, 'tcx>(
// typeck had previously found constraints that would cause them to be related.

let mut counter = 0;
let mut mk_bound_region = |span| {
let kind = ty::BrAnon(span);
let mut mk_bound_region = |kind| {
let var = ty::BoundVar::from_u32(counter);
counter += 1;
ty::BoundRegion { var, kind }
Expand All @@ -252,24 +251,23 @@ pub fn resolve_interior<'a, 'tcx>(
let origin = fcx.region_var_origin(vid);
match origin {
RegionVariableOrigin::EarlyBoundRegion(span, _) => {
mk_bound_region(Some(span))
mk_bound_region(ty::BrAnon(Some(span)))
}
_ => mk_bound_region(None),
_ => mk_bound_region(ty::BrAnon(None)),
}
}
// FIXME: these should use `BrNamed`
ty::ReEarlyBound(region) => {
mk_bound_region(Some(fcx.tcx.def_span(region.def_id)))
mk_bound_region(ty::BrNamed(region.def_id, region.name))
}
ty::ReLateBound(_, ty::BoundRegion { kind, .. })
| ty::ReFree(ty::FreeRegion { bound_region: kind, .. }) => match kind {
ty::BoundRegionKind::BrAnon(span) => mk_bound_region(span),
ty::BoundRegionKind::BrNamed(def_id, _) => {
mk_bound_region(Some(fcx.tcx.def_span(def_id)))
ty::BoundRegionKind::BrAnon(span) => mk_bound_region(ty::BrAnon(span)),
ty::BoundRegionKind::BrNamed(def_id, sym) => {
mk_bound_region(ty::BrNamed(def_id, sym))
}
ty::BoundRegionKind::BrEnv => mk_bound_region(None),
ty::BoundRegionKind::BrEnv => mk_bound_region(ty::BrAnon(None)),
},
_ => mk_bound_region(None),
_ => mk_bound_region(ty::BrAnon(None)),
};
let r = fcx.tcx.mk_re_late_bound(current_depth, br);
r
Expand All @@ -293,10 +291,7 @@ pub fn resolve_interior<'a, 'tcx>(
type_causes,
FnMutDelegate {
regions: &mut |br| {
let kind = match br.kind {
ty::BrAnon(span) => ty::BrAnon(span),
_ => br.kind,
};
let kind = br.kind;
let var = ty::BoundVar::from_usize(bound_vars.len());
bound_vars.push(ty::BoundVariableKind::Region(kind));
counter += 1;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1927,6 +1927,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
{
let span = self.tcx.def_span(def_id);
diag.span_note(span, "this closure does not fulfill the lifetime requirements");
self.suggest_for_all_lifetime_closure(span, self.tcx.hir().get_by_def_id(def_id), &exp_found, diag);
}

// It reads better to have the error origin as the final
Expand Down
78 changes: 77 additions & 1 deletion compiler/rustc_infer/src/infer/error_reporting/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_middle::traits::{
StatementAsExpression,
};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitableExt};
use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt};
use rustc_span::{sym, BytePos, Span};
use rustc_target::abi::FieldIdx;

Expand Down Expand Up @@ -536,6 +536,82 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
None
}

/// For "one type is more general than the other" errors on closures, suggest changing the lifetime
/// of the parameters to accept all lifetimes.
pub(super) fn suggest_for_all_lifetime_closure(
&self,
span: Span,
hir: hir::Node<'_>,
exp_found: &ty::error::ExpectedFound<ty::PolyTraitRef<'tcx>>,
diag: &mut Diagnostic,
) {
// 0. Extract fn_decl from hir
let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(hir::Closure { body, fn_decl, .. }), .. }) = hir else { return; };
let hir::Body { params, .. } = self.tcx.hir().body(*body);

// 1. Get the substs of the closure.
// 2. Assume exp_found is FnOnce / FnMut / Fn, we can extract function parameters from [1].
let Some(expected) = exp_found.expected.skip_binder().substs.get(1) else { return; };
let Some(found) = exp_found.found.skip_binder().substs.get(1) else { return; };
let expected = expected.unpack();
let found = found.unpack();
// 3. Extract the tuple type from Fn trait and suggest the change.
if let GenericArgKind::Type(expected) = expected &&
let GenericArgKind::Type(found) = found &&
let ty::Tuple(expected) = expected.kind() &&
let ty::Tuple(found)= found.kind() &&
expected.len() == found.len() {
let mut suggestion = "|".to_string();
let mut is_first = true;
let mut has_suggestion = false;

for (((expected, found), param_hir), arg_hir) in expected.iter()
.zip(found.iter())
.zip(params.iter())
.zip(fn_decl.inputs.iter()) {
if is_first {
is_first = false;
} else {
suggestion += ", ";
}

if let ty::Ref(expected_region, _, _) = expected.kind() &&
let ty::Ref(found_region, _, _) = found.kind() &&
expected_region.is_late_bound() &&
!found_region.is_late_bound() &&
let hir::TyKind::Infer = arg_hir.kind {
// If the expected region is late bound, the found region is not, and users are asking compiler
// to infer the type, we can suggest adding `: &_`.
if param_hir.pat.span == param_hir.ty_span {
// for `|x|`, `|_|`, `|x: impl Foo|`
let Ok(pat) = self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) else { return; };
suggestion += &format!("{}: &_", pat);
} else {
// for `|x: ty|`, `|_: ty|`
let Ok(pat) = self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) else { return; };
let Ok(ty) = self.tcx.sess.source_map().span_to_snippet(param_hir.ty_span) else { return; };
suggestion += &format!("{}: &{}", pat, ty);
}
has_suggestion = true;
} else {
let Ok(arg) = self.tcx.sess.source_map().span_to_snippet(param_hir.span) else { return; };
// Otherwise, keep it as-is.
suggestion += &arg;
}
}
suggestion += "|";

if has_suggestion {
diag.span_suggestion_verbose(
span,
"consider specifying the type of the closure parameters",
suggestion,
Applicability::MaybeIncorrect,
);
}
}
}
}

impl<'tcx> TypeErrCtxt<'_, 'tcx> {
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_middle/src/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub mod nested_filter;
pub mod place;

use crate::ty::query::Providers;
use crate::ty::{ImplSubject, TyCtxt};
use crate::ty::{EarlyBinder, ImplSubject, TyCtxt};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
use rustc_hir::def_id::{DefId, LocalDefId};
Expand Down Expand Up @@ -104,11 +104,11 @@ impl<'tcx> TyCtxt<'tcx> {
self.parent_module_from_def_id(id.owner.def_id)
}

pub fn impl_subject(self, def_id: DefId) -> ImplSubject<'tcx> {
self.impl_trait_ref(def_id)
.map(|t| t.subst_identity())
.map(ImplSubject::Trait)
.unwrap_or_else(|| ImplSubject::Inherent(self.type_of(def_id).subst_identity()))
pub fn impl_subject(self, def_id: DefId) -> EarlyBinder<ImplSubject<'tcx>> {
match self.impl_trait_ref(def_id) {
Some(t) => t.map_bound(ImplSubject::Trait),
None => self.type_of(def_id).map_bound(ImplSubject::Inherent),
}
}
}

Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,10 +708,6 @@ impl<'tcx> TyCtxt<'tcx> {
ty::EarlyBinder(self.explicit_item_bounds(def_id))
}

pub fn bound_impl_subject(self, def_id: DefId) -> ty::EarlyBinder<ty::ImplSubject<'tcx>> {
ty::EarlyBinder(self.impl_subject(def_id))
}

/// Returns names of captured upvars for closures and generators.
///
/// Here are some examples:
Expand Down
25 changes: 11 additions & 14 deletions compiler/rustc_trait_selection/src/solve/canonicalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ impl<'a, 'tcx> Canonicalizer<'a, 'tcx> {
// - var_infos: [E0, U1, E1, U1, E1, E6, U6], curr_compressed_uv: 1, next_orig_uv: 6
// - var_infos: [E0, U1, E1, U1, E1, E2, U2], curr_compressed_uv: 2, next_orig_uv: -
//
// This algorithm runs in `O(n²)` where `n` is the number of different universe
// indices in the input. This should be fine as `n` is expected to be small.
// This algorithm runs in `O(nm)` where `n` is the number of different universe
// indices in the input and `m` is the number of canonical variables.
// This should be fine as both `n` and `m` are expected to be small.
let mut curr_compressed_uv = ty::UniverseIndex::ROOT;
let mut existential_in_new_uv = false;
let mut next_orig_uv = Some(ty::UniverseIndex::ROOT);
Expand Down Expand Up @@ -245,18 +246,14 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
ty::ReError(_) => return r,
};

let existing_bound_var = match self.canonicalize_mode {
CanonicalizeMode::Input => None,
CanonicalizeMode::Response { .. } => {
self.variables.iter().position(|&v| v == r.into()).map(ty::BoundVar::from)
}
};
let var = existing_bound_var.unwrap_or_else(|| {
let var = ty::BoundVar::from(self.variables.len());
self.variables.push(r.into());
self.primitive_var_infos.push(CanonicalVarInfo { kind });
var
});
let var = ty::BoundVar::from(
self.variables.iter().position(|&v| v == r.into()).unwrap_or_else(|| {
let var = self.variables.len();
self.variables.push(r.into());
self.primitive_var_infos.push(CanonicalVarInfo { kind });
var
}),
);
let br = ty::BoundRegion { var, kind: BrAnon(None) };
self.interner().mk_re_late_bound(self.binder_index, br)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ fn negative_impl(tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId) -> b
&infcx,
ObligationCause::dummy(),
impl_env,
tcx.impl_subject(impl1_def_id),
tcx.impl_subject(impl1_def_id).subst_identity(),
) {
Ok(s) => s,
Err(err) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
impl_def_id: DefId,
impl_substs: SubstsRef<'tcx>,
) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
let subject = selcx.tcx().bound_impl_subject(impl_def_id);
let subject = selcx.tcx().impl_subject(impl_def_id);
let subject = subject.subst(selcx.tcx(), impl_substs);

let InferOk { value: subject, obligations: normalization_obligations1 } =
Expand Down
Loading