Skip to content

Commit

Permalink
Auto merge of #108789 - matthiaskrgr:rollup-nyurto8, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #108244 (Add test for semicolon recovery ICE)
 - #108746 (Don't project to RPITIT that has no default value)
 - #108764 (Tweaks to -Zdrop-tracking-mir)
 - #108770 (Improve documentation and argument naming of some TyCtxt methods)
 - #108773 (x fmt: Only check modified files locally)
 - #108775 (Use the correct bound vars in return type suggestion.)
 - #108776 (Make `x test tidy` less noisy)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 6, 2023
2 parents 816f958 + c08c69b commit 8c0f83d
Show file tree
Hide file tree
Showing 17 changed files with 151 additions and 54 deletions.
8 changes: 8 additions & 0 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1510,6 +1510,14 @@ fn opaque_type_cycle_error(
{
label_match(interior_ty.ty, interior_ty.span);
}
if tcx.sess.opts.unstable_opts.drop_tracking_mir
&& let DefKind::Generator = tcx.def_kind(closure_def_id)
{
let generator_layout = tcx.mir_generator_witnesses(closure_def_id);
for interior_ty in &generator_layout.field_tys {
label_match(interior_ty.ty, interior_ty.source_info.span);
}
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
in_trait,
..
}) => {
if in_trait {
assert!(tcx.impl_defaultness(owner).has_value());
if in_trait && !tcx.impl_defaultness(owner).has_value() {
span_bug!(tcx.def_span(def_id), "tried to get type of this RPITIT with no definition");
}
find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
}
Expand Down
45 changes: 21 additions & 24 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// This routine checks if the return type is left as default, the method is not part of an
/// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
/// type.
#[instrument(level = "trace", skip(self, err))]
pub(in super::super) fn suggest_missing_return_type(
&self,
err: &mut Diagnostic,
Expand Down Expand Up @@ -705,28 +706,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return true
}
}
hir::FnRetTy::Return(ty) => {
let span = ty.span;

if let hir::TyKind::OpaqueDef(item_id, ..) = ty.kind
&& let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(op_ty),
..
}) = self.tcx.hir().get(item_id.hir_id())
&& let hir::OpaqueTy {
bounds: [bound], ..
} = op_ty
&& let hir::GenericBound::LangItemTrait(
hir::LangItem::Future, _, _, generic_args) = bound
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
&& let hir::TypeBinding { kind, .. } = ty_binding
&& let hir::TypeBindingKind::Equality { term } = kind
&& let hir::Term::Ty(term_ty) = term {
hir::FnRetTy::Return(hir_ty) => {
let span = hir_ty.span;

if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
&& let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(op_ty),
..
}) = self.tcx.hir().get(item_id.hir_id())
&& let [hir::GenericBound::LangItemTrait(
hir::LangItem::Future, _, _, generic_args)] = op_ty.bounds
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } = ty_binding.kind
{
// Check if async function's return type was omitted.
// Don't emit suggestions if the found type is `impl Future<...>`.
debug!("suggest_missing_return_type: found = {:?}", found);
debug!(?found);
if found.is_suggestable(self.tcx, false) {
if term_ty.span.is_empty() {
if term.span.is_empty() {
err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: found.to_string() });
return true;
} else {
Expand All @@ -737,11 +734,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Only point to return type if the expected type is the return type, as if they
// are not, the expectation must have been caused by something else.
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
let ty = self.astconv().ast_ty_to_ty(ty);
debug!("suggest_missing_return_type: return type {:?}", ty);
debug!("suggest_missing_return_type: expected type {:?}", ty);
let bound_vars = self.tcx.late_bound_vars(fn_id);
debug!("return type {:?}", hir_ty);
let ty = self.astconv().ast_ty_to_ty(hir_ty);
debug!("return type {:?}", ty);
debug!("expected type {:?}", expected);
let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into());
let ty = Binder::bind_with_vars(ty, bound_vars);
let ty = self.normalize(span, ty);
let ty = self.tcx.erase_late_bound_regions(ty);
Expand Down
33 changes: 20 additions & 13 deletions compiler/rustc_middle/src/ty/trait_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,9 @@ impl<'tcx> TraitDef {
}

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

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

/// Iterate over every impl that could possibly match the
/// self type `self_ty`.
/// Iterate over every impl that could possibly match the self type `self_ty`.
///
/// `trait_def_id` MUST BE the `DefId` of a trait.
pub fn for_each_relevant_impl<F: FnMut(DefId)>(
self,
def_id: DefId,
trait_def_id: DefId,
self_ty: Ty<'tcx>,
mut f: F,
) {
let _: Option<()> = self.find_map_relevant_impl(def_id, self_ty, |did| {
let _: Option<()> = self.find_map_relevant_impl(trait_def_id, self_ty, |did| {
f(did);
None
});
}

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

/// Applies function to every impl that could possibly match the self type `self_ty` and returns
/// the first non-none value.
///
/// `trait_def_id` MUST BE the `DefId` of a trait.
pub fn find_map_relevant_impl<T, F: FnMut(DefId) -> Option<T>>(
self,
def_id: DefId,
trait_def_id: DefId,
self_ty: Ty<'tcx>,
mut f: F,
) -> Option<T> {
Expand All @@ -156,7 +161,7 @@ impl<'tcx> TyCtxt<'tcx> {
//
// If we want to be faster, we could have separate queries for
// blanket and non-blanket impls, and compare them separately.
let impls = self.trait_impls_of(def_id);
let impls = self.trait_impls_of(trait_def_id);

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

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

blanket_impls.iter().chain(non_blanket_impls.iter().flat_map(|(_, v)| v)).cloned()
}
Expand Down
14 changes: 8 additions & 6 deletions compiler/rustc_mir_transform/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1872,12 +1872,14 @@ fn check_must_not_suspend_def(
data: SuspendCheckData<'_>,
) -> bool {
if let Some(attr) = tcx.get_attr(def_id, sym::must_not_suspend) {
let msg = format!(
"{}`{}`{} held across a suspend point, but should not be",
data.descr_pre,
tcx.def_path_str(def_id),
data.descr_post,
);
let msg = rustc_errors::DelayDm(|| {
format!(
"{}`{}`{} held across a suspend point, but should not be",
data.descr_pre,
tcx.def_path_str(def_id),
data.descr_post,
)
});
tcx.struct_span_lint_hir(
rustc_session::lint::builtin::MUST_NOT_SUSPEND,
hir_id,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/solve/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
&mut self,
_: &InferCtxt<'tcx>,
) -> Vec<PredicateObligation<'tcx>> {
unimplemented!()
std::mem::take(&mut self.obligations)
}
}
3 changes: 2 additions & 1 deletion compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2199,7 +2199,8 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
Err(guar) => return Progress::error(tcx, guar),
};
// We don't support specialization for RPITITs anyways... yet.
if !leaf_def.is_final() {
// Also don't try to project to an RPITIT that has no value
if !leaf_def.is_final() || !leaf_def.item.defaultness(tcx).has_value() {
return Progress { term: tcx.ty_error_misc().into(), obligations };
}

Expand Down
12 changes: 9 additions & 3 deletions src/bootstrap/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use crate::builder::Builder;
use crate::util::{output, program_out_of_date, t};
use build_helper::ci::CiEnv;
use build_helper::git::get_git_modified_files;
use ignore::WalkBuilder;
use std::collections::VecDeque;
Expand Down Expand Up @@ -144,8 +145,10 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
let untracked_paths = untracked_paths_output
.lines()
.filter(|entry| entry.starts_with("??"))
.map(|entry| {
entry.split(' ').nth(1).expect("every git status entry should list a path")
.filter_map(|entry| {
let path =
entry.split(' ').nth(1).expect("every git status entry should list a path");
path.ends_with(".rs").then_some(path)
});
for untracked_path in untracked_paths {
println!("skip untracked path {} during rustfmt invocations", untracked_path);
Expand All @@ -156,7 +159,10 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
// preventing the latter from being formatted.
ignore_fmt.add(&format!("!/{}", untracked_path)).expect(&untracked_path);
}
if !check && paths.is_empty() {
// Only check modified files locally to speed up runtime.
// We still check all files in CI to avoid bugs in `get_modified_rs_files` letting regressions slip through;
// we also care about CI time less since this is still very fast compared to building the compiler.
if !CiEnv::is_ci() && paths.is_empty() {
match get_modified_rs_files(build) {
Ok(Some(files)) => {
for file in files {
Expand Down
6 changes: 4 additions & 2 deletions src/tools/tidy/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut

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

// Stage 2: check list has docs
let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut errors, verbose);
Expand Down
2 changes: 0 additions & 2 deletions src/tools/tidy/src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,6 @@ pub fn check(
for line in lines {
println!("* {line}");
}
} else {
println!("* {} features", features.len());
}

CollectedFeatures { lib: lib_features, lang: features }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#![feature(return_position_impl_trait_in_trait)]
//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete

trait MyTrait {
fn foo(&self) -> impl Sized;
fn bar(&self) -> impl Sized;
}

impl MyTrait for i32 {
//~^ ERROR not all trait items implemented, missing: `foo`
fn bar(&self) -> impl Sized {
self.foo()
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/dont-project-to-rpitit-with-no-value.rs:1:12
|
LL | #![feature(return_position_impl_trait_in_trait)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= note: `#[warn(incomplete_features)]` on by default

error[E0046]: not all trait items implemented, missing: `foo`
--> $DIR/dont-project-to-rpitit-with-no-value.rs:9:1
|
LL | fn foo(&self) -> impl Sized;
| ---------------------------- `foo` from trait
...
LL | impl MyTrait for i32 {
| ^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0046`.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ error[E0720]: cannot resolve opaque type
|
LL | fn generator_hold() -> impl Sized {
| ^^^^^^^^^^ recursive opaque type
...
LL | let x = generator_hold();
| - generator captures itself here

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
Expand Down
5 changes: 5 additions & 0 deletions tests/ui/parser/issues/issue-108242-semicolon-recovery.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fn foo() {}
fn main() {
foo(;
foo(;
} //~ ERROR mismatched closing delimiter
13 changes: 13 additions & 0 deletions tests/ui/parser/issues/issue-108242-semicolon-recovery.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: mismatched closing delimiter: `}`
--> $DIR/issue-108242-semicolon-recovery.rs:4:8
|
LL | fn main() {
| - closing delimiter possibly meant for this
LL | foo(;
LL | foo(;
| ^ unclosed delimiter
LL | }
| ^ mismatched closing delimiter

error: aborting due to previous error

6 changes: 6 additions & 0 deletions tests/ui/suggestions/issue-107860.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// edition: 2021

async fn str<T>(T: &str) -> &str { &str }
//~^ ERROR mismatched types

fn main() {}
12 changes: 12 additions & 0 deletions tests/ui/suggestions/issue-107860.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0308]: mismatched types
--> $DIR/issue-107860.rs:3:36
|
LL | async fn str<T>(T: &str) -> &str { &str }
| ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<...>}`
|
= note: expected reference `&str`
found reference `&for<'a> fn(&'a str) -> impl Future<Output = &'a str> {str::<_>}`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

0 comments on commit 8c0f83d

Please sign in to comment.