Skip to content

Commit

Permalink
Auto merge of rust-lang#129242 - jieyouxu:rollup-1yhzl81, r=jieyouxu
Browse files Browse the repository at this point in the history
Rollup of 4 pull requests

Successful merges:

 - rust-lang#128084 (Suggest adding Result return type for associated method in E0277.)
 - rust-lang#129187 (bootstrap: fix clean's remove_dir_all implementation)
 - rust-lang#129208 (Fix order of normalization and recursion in const folding.)
 - rust-lang#129228 (crashes: more tests)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Aug 18, 2024
2 parents 6de928d + 2e243da commit 88a596a
Show file tree
Hide file tree
Showing 14 changed files with 252 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4610,6 +4610,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
})
}

// For E0277 when use `?` operator, suggest adding
// a suitable return type in `FnSig`, and a default
// return value at the end of the function's body.
pub(super) fn suggest_add_result_as_return_type(
&self,
obligation: &PredicateObligation<'tcx>,
Expand All @@ -4620,19 +4623,47 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
return;
}

// Only suggest for local function and associated method,
// because this suggest adding both return type in
// the `FnSig` and a default return value in the body, so it
// is not suitable for foreign function without a local body,
// and neighter for trait method which may be also implemented
// in other place, so shouldn't change it's FnSig.
fn choose_suggest_items<'tcx, 'hir>(
tcx: TyCtxt<'tcx>,
node: hir::Node<'hir>,
) -> Option<(&'hir hir::FnDecl<'hir>, hir::BodyId)> {
match node {
hir::Node::Item(item) if let hir::ItemKind::Fn(sig, _, body_id) = item.kind => {
Some((sig.decl, body_id))
}
hir::Node::ImplItem(item)
if let hir::ImplItemKind::Fn(sig, body_id) = item.kind =>
{
let parent = tcx.parent_hir_node(item.hir_id());
if let hir::Node::Item(item) = parent
&& let hir::ItemKind::Impl(imp) = item.kind
&& imp.of_trait.is_none()
{
return Some((sig.decl, body_id));
}
None
}
_ => None,
}
}

let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id);
if let hir::Node::Item(item) = node
&& let hir::ItemKind::Fn(sig, _, body_id) = item.kind
&& let hir::FnRetTy::DefaultReturn(ret_span) = sig.decl.output
if let Some((fn_decl, body_id)) = choose_suggest_items(self.tcx, node)
&& let hir::FnRetTy::DefaultReturn(ret_span) = fn_decl.output
&& self.tcx.is_diagnostic_item(sym::FromResidual, trait_pred.def_id())
&& trait_pred.skip_binder().trait_ref.args.type_at(0).is_unit()
&& let ty::Adt(def, _) = trait_pred.skip_binder().trait_ref.args.type_at(1).kind()
&& self.tcx.is_diagnostic_item(sym::Result, def.did())
{
let body = self.tcx.hir().body(body_id);
let mut sugg_spans =
vec![(ret_span, " -> Result<(), Box<dyn std::error::Error>>".to_string())];

let body = self.tcx.hir().body(body_id);
if let hir::ExprKind::Block(b, _) = body.value.kind
&& b.expr.is_none()
{
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_trait_selection/src/traits/query/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,14 +333,14 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
return Ok(constant);
}

let constant = constant.try_super_fold_with(self)?;
debug!(?constant, ?self.param_env);
Ok(crate::traits::with_replaced_escaping_bound_vars(
let constant = crate::traits::with_replaced_escaping_bound_vars(
self.infcx,
&mut self.universes,
constant,
|constant| constant.normalize(self.infcx.tcx, self.param_env),
))
);
debug!(?constant, ?self.param_env);
constant.try_super_fold_with(self)
}

#[inline]
Expand Down
93 changes: 15 additions & 78 deletions src/bootstrap/src/core/build_steps/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//! directory unless the `--all` flag is present.

use std::fs;
use std::io::{self, ErrorKind};
use std::path::Path;

use crate::core::builder::{crate_description, Builder, RunConfig, ShouldRun, Step};
Expand Down Expand Up @@ -101,11 +100,11 @@ fn clean(build: &Build, all: bool, stage: Option<u32>) {
return;
}

rm_rf("tmp".as_ref());
remove_dir_recursive("tmp");

// Clean the entire build directory
if all {
rm_rf(&build.out);
remove_dir_recursive(&build.out);
return;
}

Expand Down Expand Up @@ -136,17 +135,17 @@ fn clean_specific_stage(build: &Build, stage: u32) {
}

let path = t!(entry.path().canonicalize());
rm_rf(&path);
remove_dir_recursive(&path);
}
}
}

fn clean_default(build: &Build) {
rm_rf(&build.out.join("tmp"));
rm_rf(&build.out.join("dist"));
rm_rf(&build.out.join("bootstrap").join(".last-warned-change-id"));
rm_rf(&build.out.join("bootstrap-shims-dump"));
rm_rf(&build.out.join("rustfmt.stamp"));
remove_dir_recursive(build.out.join("tmp"));
remove_dir_recursive(build.out.join("dist"));
remove_dir_recursive(build.out.join("bootstrap").join(".last-warned-change-id"));
remove_dir_recursive(build.out.join("bootstrap-shims-dump"));
remove_dir_recursive(build.out.join("rustfmt.stamp"));

let mut hosts: Vec<_> = build.hosts.iter().map(|t| build.out.join(t)).collect();
// After cross-compilation, artifacts of the host architecture (which may differ from build.host)
Expand All @@ -166,78 +165,16 @@ fn clean_default(build: &Build) {
continue;
}
let path = t!(entry.path().canonicalize());
rm_rf(&path);
remove_dir_recursive(&path);
}
}
}

fn rm_rf(path: &Path) {
match path.symlink_metadata() {
Err(e) => {
if e.kind() == ErrorKind::NotFound {
return;
}
panic!("failed to get metadata for file {}: {}", path.display(), e);
}
Ok(metadata) => {
if metadata.file_type().is_file() || metadata.file_type().is_symlink() {
do_op(path, "remove file", |p| match fs::remove_file(p) {
#[cfg(windows)]
Err(e)
if e.kind() == std::io::ErrorKind::PermissionDenied
&& p.file_name().and_then(std::ffi::OsStr::to_str)
== Some("bootstrap.exe") =>
{
eprintln!("WARNING: failed to delete '{}'.", p.display());
Ok(())
}
r => r,
});

return;
}

for file in t!(fs::read_dir(path)) {
rm_rf(&t!(file).path());
}

do_op(path, "remove dir", |p| match fs::remove_dir(p) {
// Check for dir not empty on Windows
// FIXME: Once `ErrorKind::DirectoryNotEmpty` is stabilized,
// match on `e.kind()` instead.
#[cfg(windows)]
Err(e) if e.raw_os_error() == Some(145) => Ok(()),
r => r,
});
}
};
}

fn do_op<F>(path: &Path, desc: &str, mut f: F)
where
F: FnMut(&Path) -> io::Result<()>,
{
match f(path) {
Ok(()) => {}
// On windows we can't remove a readonly file, and git will often clone files as readonly.
// As a result, we have some special logic to remove readonly files on windows.
// This is also the reason that we can't use things like fs::remove_dir_all().
#[cfg(windows)]
Err(ref e) if e.kind() == ErrorKind::PermissionDenied => {
let m = t!(path.symlink_metadata());
let mut p = m.permissions();
p.set_readonly(false);
t!(fs::set_permissions(path, p));
f(path).unwrap_or_else(|e| {
// Delete symlinked directories on Windows
if m.file_type().is_symlink() && path.is_dir() && fs::remove_dir(path).is_ok() {
return;
}
panic!("failed to {} {}: {}", desc, path.display(), e);
});
}
Err(e) => {
panic!("failed to {} {}: {}", desc, path.display(), e);
}
/// Wrapper for [`std::fs::remove_dir_all`] that panics on failure and prints the `path` we failed
/// on.
fn remove_dir_recursive<P: AsRef<Path>>(path: P) {
let path = path.as_ref();
if let Err(e) = fs::remove_dir_all(path) {
panic!("failed to `remove_dir_all` at `{}`: {e}", path.display());
}
}
7 changes: 7 additions & 0 deletions tests/crashes/129150.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//@ known-bug: rust-lang/rust#129150
//@ only-x86_64
use std::arch::x86_64::_mm_blend_ps;

pub fn main() {
_mm_blend_ps(1, 2, &const {} );
}
7 changes: 7 additions & 0 deletions tests/crashes/129166.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//@ known-bug: rust-lang/rust#129166

fn main() {
#[cfg_eval]
#[cfg]
0
}
5 changes: 5 additions & 0 deletions tests/crashes/129205.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//@ known-bug: rust-lang/rust#129205

fn x<T: Copy>() {
T::try_from();
}
11 changes: 11 additions & 0 deletions tests/crashes/129209.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//@ known-bug: rust-lang/rust#129209

impl<
const N: usize = {
static || {
Foo([0; X]);
}
},
> PartialEq for True
{
}
30 changes: 30 additions & 0 deletions tests/crashes/129214.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//@ known-bug: rust-lang/rust#129214
//@ compile-flags: -Zvalidate-mir -Copt-level=3 --crate-type=lib

trait to_str {}

trait map<T> {
fn map<U, F>(&self, f: F) -> Vec<U>
where
F: FnMut(&Box<usize>) -> U;
}
impl<T> map<T> for Vec<T> {
fn map<U, F>(&self, mut f: F) -> Vec<U>
where
F: FnMut(&T) -> U,
{
let mut r = Vec::new();
for i in self {
r.push(f(i));
}
r
}
}

fn foo<U, T: map<U>>(x: T) -> Vec<String> {
x.map(|_e| "hi".to_string())
}

pub fn main() {
assert_eq!(foo(vec![1]), ["hi".to_string()]);
}
11 changes: 11 additions & 0 deletions tests/crashes/129216.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//@ known-bug: rust-lang/rust#129216

trait Mirror {
type Assoc;
}

struct Foo;

fn main() {
<Foo as Mirror>::Assoc::new();
}
26 changes: 26 additions & 0 deletions tests/crashes/129219.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//@ known-bug: rust-lang/rust#129219
//@ compile-flags: -Zmir-opt-level=5 -Zvalidate-mir --edition=2018

use core::marker::Unsize;

pub trait CastTo<T: ?Sized>: Unsize<T> {}

impl<T: ?Sized, U: ?Sized> CastTo<T> for U {}

impl<T: ?Sized> Cast for T {}
pub trait Cast {
fn cast<T: ?Sized>(&self) -> &T
where
Self: CastTo<T>,
{
self
}
}

pub trait Foo {}
impl Foo for [i32; 0] {}

fn main() {
let x: &dyn Foo = &[];
let x = x.cast::<[i32]>();
}
25 changes: 25 additions & 0 deletions tests/ui/const-generics/const-ty-is-normalized.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//@ compile-flags: -Cdebuginfo=2 --crate-type=lib
//@ build-pass
#![feature(adt_const_params)]

const N_ISLANDS: usize = 4;

pub type Matrix = [[usize; N_ISLANDS]; N_ISLANDS];

const EMPTY_MATRIX: Matrix = [[0; N_ISLANDS]; N_ISLANDS];

const fn to_matrix() -> Matrix {
EMPTY_MATRIX
}

const BRIDGE_MATRIX: [[usize; N_ISLANDS]; N_ISLANDS] = to_matrix();

pub struct Walk<const CURRENT: usize, const REMAINING: Matrix> {
_p: (),
}

impl Walk<0, BRIDGE_MATRIX> {
pub const fn new() -> Self {
Self { _p: () }
}
}
19 changes: 19 additions & 0 deletions tests/ui/return/return-from-residual-sugg-issue-125997.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,25 @@ macro_rules! mac {
};
}

struct A;

impl A {
fn test4(&self) -> Result<(), Box<dyn std::error::Error>> {
let mut _file = File::create("foo.txt")?;
//~^ ERROR the `?` operator can only be used in a method

Ok(())
}

fn test5(&self) -> Result<(), Box<dyn std::error::Error>> {
let mut _file = File::create("foo.txt")?;
//~^ ERROR the `?` operator can only be used in a method
println!();

Ok(())
}
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut _file = File::create("foo.txt")?;
//~^ ERROR the `?` operator can only be used in a function
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/return/return-from-residual-sugg-issue-125997.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@ macro_rules! mac {
};
}

struct A;

impl A {
fn test4(&self) {
let mut _file = File::create("foo.txt")?;
//~^ ERROR the `?` operator can only be used in a method
}

fn test5(&self) {
let mut _file = File::create("foo.txt")?;
//~^ ERROR the `?` operator can only be used in a method
println!();
}
}

fn main() {
let mut _file = File::create("foo.txt")?;
//~^ ERROR the `?` operator can only be used in a function
Expand Down
Loading

0 comments on commit 88a596a

Please sign in to comment.