Skip to content

Rollup of 4 pull requests #129242

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

Closed
wants to merge 8 commits into from
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
Loading