Skip to content

Commit 8c0f83d

Browse files
committed
Auto merge of rust-lang#108789 - matthiaskrgr:rollup-nyurto8, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#108244 (Add test for semicolon recovery ICE) - rust-lang#108746 (Don't project to RPITIT that has no default value) - rust-lang#108764 (Tweaks to -Zdrop-tracking-mir) - rust-lang#108770 (Improve documentation and argument naming of some TyCtxt methods) - rust-lang#108773 (x fmt: Only check modified files locally) - rust-lang#108775 (Use the correct bound vars in return type suggestion.) - rust-lang#108776 (Make `x test tidy` less noisy) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 816f958 + c08c69b commit 8c0f83d

File tree

17 files changed

+151
-54
lines changed

17 files changed

+151
-54
lines changed

Diff for: compiler/rustc_hir_analysis/src/check/check.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1510,6 +1510,14 @@ fn opaque_type_cycle_error(
15101510
{
15111511
label_match(interior_ty.ty, interior_ty.span);
15121512
}
1513+
if tcx.sess.opts.unstable_opts.drop_tracking_mir
1514+
&& let DefKind::Generator = tcx.def_kind(closure_def_id)
1515+
{
1516+
let generator_layout = tcx.mir_generator_witnesses(closure_def_id);
1517+
for interior_ty in &generator_layout.field_tys {
1518+
label_match(interior_ty.ty, interior_ty.source_info.span);
1519+
}
1520+
}
15131521
}
15141522
}
15151523
}

Diff for: compiler/rustc_hir_analysis/src/collect/type_of.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
344344
in_trait,
345345
..
346346
}) => {
347-
if in_trait {
348-
assert!(tcx.impl_defaultness(owner).has_value());
347+
if in_trait && !tcx.impl_defaultness(owner).has_value() {
348+
span_bug!(tcx.def_span(def_id), "tried to get type of this RPITIT with no definition");
349349
}
350350
find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
351351
}

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+21-24
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
669669
/// This routine checks if the return type is left as default, the method is not part of an
670670
/// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
671671
/// type.
672+
#[instrument(level = "trace", skip(self, err))]
672673
pub(in super::super) fn suggest_missing_return_type(
673674
&self,
674675
err: &mut Diagnostic,
@@ -705,28 +706,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
705706
return true
706707
}
707708
}
708-
hir::FnRetTy::Return(ty) => {
709-
let span = ty.span;
710-
711-
if let hir::TyKind::OpaqueDef(item_id, ..) = ty.kind
712-
&& let hir::Node::Item(hir::Item {
713-
kind: hir::ItemKind::OpaqueTy(op_ty),
714-
..
715-
}) = self.tcx.hir().get(item_id.hir_id())
716-
&& let hir::OpaqueTy {
717-
bounds: [bound], ..
718-
} = op_ty
719-
&& let hir::GenericBound::LangItemTrait(
720-
hir::LangItem::Future, _, _, generic_args) = bound
721-
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
722-
&& let hir::TypeBinding { kind, .. } = ty_binding
723-
&& let hir::TypeBindingKind::Equality { term } = kind
724-
&& let hir::Term::Ty(term_ty) = term {
709+
hir::FnRetTy::Return(hir_ty) => {
710+
let span = hir_ty.span;
711+
712+
if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
713+
&& let hir::Node::Item(hir::Item {
714+
kind: hir::ItemKind::OpaqueTy(op_ty),
715+
..
716+
}) = self.tcx.hir().get(item_id.hir_id())
717+
&& let [hir::GenericBound::LangItemTrait(
718+
hir::LangItem::Future, _, _, generic_args)] = op_ty.bounds
719+
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
720+
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } = ty_binding.kind
721+
{
725722
// Check if async function's return type was omitted.
726723
// Don't emit suggestions if the found type is `impl Future<...>`.
727-
debug!("suggest_missing_return_type: found = {:?}", found);
724+
debug!(?found);
728725
if found.is_suggestable(self.tcx, false) {
729-
if term_ty.span.is_empty() {
726+
if term.span.is_empty() {
730727
err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: found.to_string() });
731728
return true;
732729
} else {
@@ -737,11 +734,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
737734

738735
// Only point to return type if the expected type is the return type, as if they
739736
// are not, the expectation must have been caused by something else.
740-
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
741-
let ty = self.astconv().ast_ty_to_ty(ty);
742-
debug!("suggest_missing_return_type: return type {:?}", ty);
743-
debug!("suggest_missing_return_type: expected type {:?}", ty);
744-
let bound_vars = self.tcx.late_bound_vars(fn_id);
737+
debug!("return type {:?}", hir_ty);
738+
let ty = self.astconv().ast_ty_to_ty(hir_ty);
739+
debug!("return type {:?}", ty);
740+
debug!("expected type {:?}", expected);
741+
let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into());
745742
let ty = Binder::bind_with_vars(ty, bound_vars);
746743
let ty = self.normalize(span, ty);
747744
let ty = self.tcx.erase_late_bound_regions(ty);

Diff for: compiler/rustc_middle/src/ty/trait_def.rs

+20-13
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ impl<'tcx> TraitDef {
100100
}
101101

102102
impl<'tcx> TyCtxt<'tcx> {
103-
pub fn for_each_impl<F: FnMut(DefId)>(self, def_id: DefId, mut f: F) {
104-
let impls = self.trait_impls_of(def_id);
103+
/// `trait_def_id` MUST BE the `DefId` of a trait.
104+
pub fn for_each_impl<F: FnMut(DefId)>(self, trait_def_id: DefId, mut f: F) {
105+
let impls = self.trait_impls_of(trait_def_id);
105106

106107
for &impl_def_id in impls.blanket_impls.iter() {
107108
f(impl_def_id);
@@ -114,26 +115,28 @@ impl<'tcx> TyCtxt<'tcx> {
114115
}
115116
}
116117

117-
/// Iterate over every impl that could possibly match the
118-
/// self type `self_ty`.
118+
/// Iterate over every impl that could possibly match the self type `self_ty`.
119+
///
120+
/// `trait_def_id` MUST BE the `DefId` of a trait.
119121
pub fn for_each_relevant_impl<F: FnMut(DefId)>(
120122
self,
121-
def_id: DefId,
123+
trait_def_id: DefId,
122124
self_ty: Ty<'tcx>,
123125
mut f: F,
124126
) {
125-
let _: Option<()> = self.find_map_relevant_impl(def_id, self_ty, |did| {
127+
let _: Option<()> = self.find_map_relevant_impl(trait_def_id, self_ty, |did| {
126128
f(did);
127129
None
128130
});
129131
}
130132

133+
/// `trait_def_id` MUST BE the `DefId` of a trait.
131134
pub fn non_blanket_impls_for_ty(
132135
self,
133-
def_id: DefId,
136+
trait_def_id: DefId,
134137
self_ty: Ty<'tcx>,
135138
) -> impl Iterator<Item = DefId> + 'tcx {
136-
let impls = self.trait_impls_of(def_id);
139+
let impls = self.trait_impls_of(trait_def_id);
137140
if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsInfer) {
138141
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
139142
return impls.iter().copied();
@@ -145,9 +148,11 @@ impl<'tcx> TyCtxt<'tcx> {
145148

146149
/// Applies function to every impl that could possibly match the self type `self_ty` and returns
147150
/// the first non-none value.
151+
///
152+
/// `trait_def_id` MUST BE the `DefId` of a trait.
148153
pub fn find_map_relevant_impl<T, F: FnMut(DefId) -> Option<T>>(
149154
self,
150-
def_id: DefId,
155+
trait_def_id: DefId,
151156
self_ty: Ty<'tcx>,
152157
mut f: F,
153158
) -> Option<T> {
@@ -156,7 +161,7 @@ impl<'tcx> TyCtxt<'tcx> {
156161
//
157162
// If we want to be faster, we could have separate queries for
158163
// blanket and non-blanket impls, and compare them separately.
159-
let impls = self.trait_impls_of(def_id);
164+
let impls = self.trait_impls_of(trait_def_id);
160165

161166
for &impl_def_id in impls.blanket_impls.iter() {
162167
if let result @ Some(_) = f(impl_def_id) {
@@ -190,9 +195,11 @@ impl<'tcx> TyCtxt<'tcx> {
190195
None
191196
}
192197

193-
/// Returns an iterator containing all impls
194-
pub fn all_impls(self, def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
195-
let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(def_id);
198+
/// Returns an iterator containing all impls for `trait_def_id`.
199+
///
200+
/// `trait_def_id` MUST BE the `DefId` of a trait.
201+
pub fn all_impls(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
202+
let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(trait_def_id);
196203

197204
blanket_impls.iter().chain(non_blanket_impls.iter().flat_map(|(_, v)| v)).cloned()
198205
}

Diff for: compiler/rustc_mir_transform/src/generator.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1872,12 +1872,14 @@ fn check_must_not_suspend_def(
18721872
data: SuspendCheckData<'_>,
18731873
) -> bool {
18741874
if let Some(attr) = tcx.get_attr(def_id, sym::must_not_suspend) {
1875-
let msg = format!(
1876-
"{}`{}`{} held across a suspend point, but should not be",
1877-
data.descr_pre,
1878-
tcx.def_path_str(def_id),
1879-
data.descr_post,
1880-
);
1875+
let msg = rustc_errors::DelayDm(|| {
1876+
format!(
1877+
"{}`{}`{} held across a suspend point, but should not be",
1878+
data.descr_pre,
1879+
tcx.def_path_str(def_id),
1880+
data.descr_post,
1881+
)
1882+
});
18811883
tcx.struct_span_lint_hir(
18821884
rustc_session::lint::builtin::MUST_NOT_SUSPEND,
18831885
hir_id,

Diff for: compiler/rustc_trait_selection/src/solve/fulfill.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
149149
&mut self,
150150
_: &InferCtxt<'tcx>,
151151
) -> Vec<PredicateObligation<'tcx>> {
152-
unimplemented!()
152+
std::mem::take(&mut self.obligations)
153153
}
154154
}

Diff for: compiler/rustc_trait_selection/src/traits/project.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2199,7 +2199,8 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
21992199
Err(guar) => return Progress::error(tcx, guar),
22002200
};
22012201
// We don't support specialization for RPITITs anyways... yet.
2202-
if !leaf_def.is_final() {
2202+
// Also don't try to project to an RPITIT that has no value
2203+
if !leaf_def.is_final() || !leaf_def.item.defaultness(tcx).has_value() {
22032204
return Progress { term: tcx.ty_error_misc().into(), obligations };
22042205
}
22052206

Diff for: src/bootstrap/format.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use crate::builder::Builder;
44
use crate::util::{output, program_out_of_date, t};
5+
use build_helper::ci::CiEnv;
56
use build_helper::git::get_git_modified_files;
67
use ignore::WalkBuilder;
78
use std::collections::VecDeque;
@@ -144,8 +145,10 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
144145
let untracked_paths = untracked_paths_output
145146
.lines()
146147
.filter(|entry| entry.starts_with("??"))
147-
.map(|entry| {
148-
entry.split(' ').nth(1).expect("every git status entry should list a path")
148+
.filter_map(|entry| {
149+
let path =
150+
entry.split(' ').nth(1).expect("every git status entry should list a path");
151+
path.ends_with(".rs").then_some(path)
149152
});
150153
for untracked_path in untracked_paths {
151154
println!("skip untracked path {} during rustfmt invocations", untracked_path);
@@ -156,7 +159,10 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
156159
// preventing the latter from being formatted.
157160
ignore_fmt.add(&format!("!/{}", untracked_path)).expect(&untracked_path);
158161
}
159-
if !check && paths.is_empty() {
162+
// Only check modified files locally to speed up runtime.
163+
// We still check all files in CI to avoid bugs in `get_modified_rs_files` letting regressions slip through;
164+
// we also care about CI time less since this is still very fast compared to building the compiler.
165+
if !CiEnv::is_ci() && paths.is_empty() {
160166
match get_modified_rs_files(build) {
161167
Ok(Some(files)) => {
162168
for file in files {

Diff for: src/tools/tidy/src/error_codes.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut
4646

4747
// Stage 1: create list
4848
let error_codes = extract_error_codes(root_path, &mut errors);
49-
println!("Found {} error codes", error_codes.len());
50-
println!("Highest error code: `{}`", error_codes.iter().max().unwrap());
49+
if verbose {
50+
println!("Found {} error codes", error_codes.len());
51+
println!("Highest error code: `{}`", error_codes.iter().max().unwrap());
52+
}
5153

5254
// Stage 2: check list has docs
5355
let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut errors, verbose);

Diff for: src/tools/tidy/src/features.rs

-2
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,6 @@ pub fn check(
219219
for line in lines {
220220
println!("* {line}");
221221
}
222-
} else {
223-
println!("* {} features", features.len());
224222
}
225223

226224
CollectedFeatures { lib: lib_features, lang: features }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(return_position_impl_trait_in_trait)]
2+
//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete
3+
4+
trait MyTrait {
5+
fn foo(&self) -> impl Sized;
6+
fn bar(&self) -> impl Sized;
7+
}
8+
9+
impl MyTrait for i32 {
10+
//~^ ERROR not all trait items implemented, missing: `foo`
11+
fn bar(&self) -> impl Sized {
12+
self.foo()
13+
}
14+
}
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/dont-project-to-rpitit-with-no-value.rs:1:12
3+
|
4+
LL | #![feature(return_position_impl_trait_in_trait)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0046]: not all trait items implemented, missing: `foo`
11+
--> $DIR/dont-project-to-rpitit-with-no-value.rs:9:1
12+
|
13+
LL | fn foo(&self) -> impl Sized;
14+
| ---------------------------- `foo` from trait
15+
...
16+
LL | impl MyTrait for i32 {
17+
| ^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
18+
19+
error: aborting due to previous error; 1 warning emitted
20+
21+
For more information about this error, try `rustc --explain E0046`.

Diff for: tests/ui/impl-trait/recursive-impl-trait-type-indirect.drop_tracking_mir.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ error[E0720]: cannot resolve opaque type
114114
|
115115
LL | fn generator_hold() -> impl Sized {
116116
| ^^^^^^^^^^ recursive opaque type
117+
...
118+
LL | let x = generator_hold();
119+
| - generator captures itself here
117120

118121
error[E0720]: cannot resolve opaque type
119122
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn foo() {}
2+
fn main() {
3+
foo(;
4+
foo(;
5+
} //~ ERROR mismatched closing delimiter
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: mismatched closing delimiter: `}`
2+
--> $DIR/issue-108242-semicolon-recovery.rs:4:8
3+
|
4+
LL | fn main() {
5+
| - closing delimiter possibly meant for this
6+
LL | foo(;
7+
LL | foo(;
8+
| ^ unclosed delimiter
9+
LL | }
10+
| ^ mismatched closing delimiter
11+
12+
error: aborting due to previous error
13+

Diff for: tests/ui/suggestions/issue-107860.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// edition: 2021
2+
3+
async fn str<T>(T: &str) -> &str { &str }
4+
//~^ ERROR mismatched types
5+
6+
fn main() {}

Diff for: tests/ui/suggestions/issue-107860.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-107860.rs:3:36
3+
|
4+
LL | async fn str<T>(T: &str) -> &str { &str }
5+
| ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<...>}`
6+
|
7+
= note: expected reference `&str`
8+
found reference `&for<'a> fn(&'a str) -> impl Future<Output = &'a str> {str::<_>}`
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)