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 7 pull requests #129256

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b4b991e
Suggest adding Result return type for associated method in E0277.
surechen Jul 23, 2024
d5a7c45
doc: std::env::var: Returns None for names with '=' or NUL byte
evanj Aug 9, 2024
9a9cf2f
Fix bootstrap test `detect_src_and_out` on Windows
ChrisDenton Aug 17, 2024
1687c55
bootstrap: fix clean's `remove_dir_all` implementation
jieyouxu Aug 17, 2024
c7832b8
move `Build::update_submodule` to `Config::update_submodule`
onur-ozkan Aug 18, 2024
3d0f3b2
bypass `dry_run` if the command is `run_always`
onur-ozkan Aug 18, 2024
1ca2708
sync llvm submodule during config parse
onur-ozkan Aug 18, 2024
b0023f5
code review improvements
evanj Aug 18, 2024
dc47665
Typo
smoelius Aug 18, 2024
3a9bf45
Check that `#[may_dangle]` is properly applied
GoldsteinE Aug 18, 2024
df6cb95
Fix wording of misapplied `must_not_suspend` error
GoldsteinE Aug 18, 2024
5ac1624
Rollup merge of #128084 - surechen:fix_125997_v1, r=cjgillot
matthiaskrgr Aug 18, 2024
e9fe807
Rollup merge of #128902 - evanj:evan.jones/env-var-doc, r=workingjubilee
matthiaskrgr Aug 18, 2024
cba68a6
Rollup merge of #129187 - jieyouxu:squeaky-clean-windows-symlinks, r=…
matthiaskrgr Aug 18, 2024
427cb70
Rollup merge of #129194 - ChrisDenton:detect-src, r=Mark-Simulacrum
matthiaskrgr Aug 18, 2024
3f3230b
Rollup merge of #129231 - onur-ozkan:improve-submodule-updates, r=Mar…
matthiaskrgr Aug 18, 2024
3d9a6ad
Rollup merge of #129235 - GoldsteinE:check-may-dangle, r=compiler-errors
matthiaskrgr Aug 18, 2024
a9919ec
Rollup merge of #129245 - smoelius:patch-1, r=lqd
matthiaskrgr Aug 18, 2024
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
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1395,7 +1395,7 @@ pub struct LetExpr<'hir> {
pub pat: &'hir Pat<'hir>,
pub ty: Option<&'hir Ty<'hir>>,
pub init: &'hir Expr<'hir>,
/// `Recovered::Yes` when this let expressions is not in a syntanctically valid location.
/// `Recovered::Yes` when this let expressions is not in a syntactically valid location.
/// Used to prevent building MIR in such situations.
pub recovered: ast::Recovered,
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,9 @@ passes_macro_export_on_decl_macro =
passes_macro_use =
`#[{$name}]` only has an effect on `extern crate` and modules
passes_may_dangle =
`#[may_dangle]` must be applied to a lifetime or type generic parameter in `Drop` impl
passes_maybe_string_interpolation = you might have meant to use string interpolation in this string literal
passes_missing_const_err =
attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
Expand Down Expand Up @@ -475,8 +478,8 @@ passes_multiple_start_functions =
.previous = previous `#[start]` function here
passes_must_not_suspend =
`must_not_suspend` attribute should be applied to a struct, enum, or trait
.label = is not a struct, enum, or trait
`must_not_suspend` attribute should be applied to a struct, enum, union, or trait
.label = is not a struct, enum, union, or trait
passes_must_use_async =
`must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
Expand Down
25 changes: 23 additions & 2 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
[sym::must_use, ..] => self.check_must_use(hir_id, attr, target),
[sym::may_dangle, ..] => self.check_may_dangle(hir_id, attr),
[sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target),
[sym::rustc_allow_incoherent_impl, ..] => {
self.check_allow_incoherent_impl(attr, span, target)
Expand Down Expand Up @@ -255,7 +256,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::cfg_attr
// need to be fixed
| sym::cfi_encoding // FIXME(cfi_encoding)
| sym::may_dangle // FIXME(dropck_eyepatch)
| sym::pointee // FIXME(derive_smart_pointer)
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
| sym::used // handled elsewhere to restrict to static items
Expand Down Expand Up @@ -1363,7 +1363,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}

/// Checks if `#[must_not_suspend]` is applied to a function.
/// Checks if `#[must_not_suspend]` is applied to a struct, enum, union, or trait.
fn check_must_not_suspend(&self, attr: &Attribute, span: Span, target: Target) {
match target {
Target::Struct | Target::Enum | Target::Union | Target::Trait => {}
Expand All @@ -1373,6 +1373,27 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}

/// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
fn check_may_dangle(&self, hir_id: HirId, attr: &Attribute) {
if let hir::Node::GenericParam(param) = self.tcx.hir_node(hir_id)
&& matches!(
param.kind,
hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. }
)
&& matches!(param.source, hir::GenericParamSource::Generics)
&& let parent_hir_id = self.tcx.parent_hir_id(hir_id)
&& let hir::Node::Item(item) = self.tcx.hir_node(parent_hir_id)
&& let hir::ItemKind::Impl(impl_) = item.kind
&& let Some(trait_) = impl_.of_trait
&& let Some(def_id) = trait_.trait_def_id()
&& self.tcx.is_lang_item(def_id, hir::LangItem::Drop)
{
return;
}

self.dcx().emit_err(errors::InvalidMayDangle { attr_span: attr.span });
}

/// Checks if `#[cold]` is applied to a non-function.
fn check_cold(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
match target {
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,13 @@ pub struct NonExportedMacroInvalidAttrs {
pub attr_span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_may_dangle)]
pub struct InvalidMayDangle {
#[primary_span]
pub attr_span: Span,
}

#[derive(LintDiagnostic)]
#[diag(passes_unused_duplicate)]
pub struct UnusedDuplicate {
Expand Down
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
11 changes: 5 additions & 6 deletions library/std/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,12 @@ impl fmt::Debug for VarsOs {
///
/// # Errors
///
/// This function will return an error if the environment variable isn't set.
/// Returns [`VarError::NotPresent`] if:
/// - The variable is not set.
/// - The variable's name contains an equal sign or NUL (`'='` or `'\0'`).
///
/// This function may return an error if the environment variable's name contains
/// the equal sign character (`=`) or the NUL character.
///
/// This function will return an error if the environment variable's value is
/// not valid Unicode. If this is not desired, consider using [`var_os`].
/// Returns [`VarError::NotUnicode`] if the variable's value is not valid
/// Unicode. If this is not desired, consider using [`var_os`].
///
/// # Examples
///
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());
}
}
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/build_steps/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub fn prebuilt_llvm_config(builder: &Builder<'_>, target: TargetSelection) -> L

// Initialize the llvm submodule if not initialized already.
// If submodules are disabled, this does nothing.
builder.update_submodule("src/llvm-project");
builder.config.update_submodule("src/llvm-project");

let root = "src/llvm-project/llvm";
let out_dir = builder.llvm_out(target);
Expand Down
Loading
Loading