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 6 pull requests #123628

Merged
merged 13 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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_driver_impl/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ driver_impl_ice = the compiler unexpectedly panicked. this is a bug.
driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url}
driver_impl_ice_bug_report_internal_feature = using internal features is not supported and expected to cause internal compiler errors when used incorrectly
driver_impl_ice_bug_report_outdated =
it seems that this compiler `{$version}` is outdated, a newer nightly should have been released in the mean time
it seems that this compiler `{$version}` is outdated, a newer nightly should have been released in the meantime
.update = please consider running `rustup update nightly` to update the nightly channel and check if this problem still persists
.url = if the problem still persists, we would appreciate a bug report: {$bug_report_url}
driver_impl_ice_exclude_cargo_defaults = some of the compiler flags provided by cargo are hidden
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,8 @@ declare_features! (
(accepted, type_alias_enum_variants, "1.37.0", Some(49683)),
/// Allows macros to appear in the type position.
(accepted, type_macros, "1.13.0", Some(27245)),
/// Allows using type privacy lints (`private_interfaces`, `private_bounds`, `unnameable_types`).
(accepted, type_privacy_lints, "CURRENT_RUSTC_VERSION", Some(48054)),
/// Allows `const _: TYPE = VALUE`.
(accepted, underscore_const_names, "1.37.0", Some(54912)),
/// Allows `use path as _;` and `extern crate c as _;`.
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,6 @@ declare_features! (
/// Allows creation of instances of a struct by moving fields that have
/// not changed from prior instances of the same struct (RFC #2528)
(unstable, type_changing_struct_update, "1.58.0", Some(86555)),
/// Allows using type privacy lints (`private_interfaces`, `private_bounds`, `unnameable_types`).
(unstable, type_privacy_lints, "1.72.0", Some(48054)),
/// Enables rustc to generate code that instructs libstd to NOT ignore SIGPIPE.
(unstable, unix_sigpipe, "1.65.0", Some(97889)),
/// Allows unnamed fields of struct and union type
Expand Down
41 changes: 34 additions & 7 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,19 @@ use rustc_middle::mir::Mutability;
use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::cast::{CastKind, CastTy};
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitableExt, VariantDef};
use rustc_session::lint;
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_span::DUMMY_SP;
use rustc_trait_selection::infer::InferCtxtExt;

/// Reifies a cast check to be checked once we have full type information for
/// a function context.
#[derive(Debug)]
pub struct CastCheck<'tcx> {
pub(crate) struct CastCheck<'tcx> {
/// The expression whose value is being casted
expr: &'tcx hir::Expr<'tcx>,
/// The source type for the cast expression
Expand All @@ -60,8 +62,6 @@ pub struct CastCheck<'tcx> {
cast_ty: Ty<'tcx>,
cast_span: Span,
span: Span,
/// whether the cast is made in a const context or not.
pub constness: hir::Constness,
}

/// The kind of pointer and associated metadata (thin, length or vtable) - we
Expand Down Expand Up @@ -194,18 +194,45 @@ fn make_invalid_casting_error<'a, 'tcx>(
)
}

/// If a cast from `from_ty` to `to_ty` is valid, returns a `Some` containing the kind
/// of the cast.
///
/// This is a helper used from clippy.
pub fn check_cast<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
e: &'tcx hir::Expr<'tcx>,
from_ty: Ty<'tcx>,
to_ty: Ty<'tcx>,
) -> Option<CastKind> {
let hir_id = e.hir_id;
let local_def_id = hir_id.owner.def_id;

let root_ctxt = crate::TypeckRootCtxt::new(tcx, local_def_id);
let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, local_def_id);

if let Ok(check) = CastCheck::new(
&fn_ctxt, e, from_ty, to_ty,
// We won't show any errors to the user, so the span is irrelevant here.
DUMMY_SP, DUMMY_SP,
) {
check.do_check(&fn_ctxt).ok()
} else {
None
}
}

impl<'a, 'tcx> CastCheck<'tcx> {
pub fn new(
pub(crate) fn new(
fcx: &FnCtxt<'a, 'tcx>,
expr: &'tcx hir::Expr<'tcx>,
expr_ty: Ty<'tcx>,
cast_ty: Ty<'tcx>,
cast_span: Span,
span: Span,
constness: hir::Constness,
) -> Result<CastCheck<'tcx>, ErrorGuaranteed> {
let expr_span = expr.span.find_ancestor_inside(span).unwrap_or(expr.span);
let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span, constness };
let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span };

// For better error messages, check for some obviously unsized
// cases now. We do a more thorough check at the end, once
Expand Down Expand Up @@ -644,7 +671,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
/// Checks a cast, and report an error if one exists. In some cases, this
/// can return Ok and create type errors in the fcx rather than returning
/// directly. coercion-cast is handled in check instead of here.
pub fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
use rustc_middle::ty::cast::CastTy::*;
use rustc_middle::ty::cast::IntTy::*;

Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

/// Check whether `ty` can be coerced to `output_ty`.
/// Used from clippy.
pub fn can_coerce<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
body_id: LocalDefId,
ty: Ty<'tcx>,
output_ty: Ty<'tcx>,
) -> bool {
let root_ctxt = crate::typeck_root_ctxt::TypeckRootCtxt::new(tcx, body_id);
let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, body_id);
fn_ctxt.can_coerce(ty, output_ty)
}

/// CoerceMany encapsulates the pattern you should use when you have
/// many expressions that are all getting coerced to a common
/// type. This arises, for example, when you have a match (the result
Expand Down
10 changes: 1 addition & 9 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1390,15 +1390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
// Defer other checks until we're done type checking.
let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
match cast::CastCheck::new(
self,
e,
t_expr,
t_cast,
t.span,
expr.span,
hir::Constness::NotConst,
) {
match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
Ok(cast_check) => {
debug!(
"check_expr_cast: deferring cast from {:?} to {:?}: {:?}",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use std::ops::Deref;
///
/// [`ItemCtxt`]: rustc_hir_analysis::collect::ItemCtxt
/// [`InferCtxt`]: infer::InferCtxt
pub struct FnCtxt<'a, 'tcx> {
pub(crate) struct FnCtxt<'a, 'tcx> {
pub(super) body_id: LocalDefId,

/// The parameter environment used for proving trait obligations
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ mod typeck_root_ctxt;
mod upvar;
mod writeback;

pub use fn_ctxt::FnCtxt;
pub use typeck_root_ctxt::TypeckRootCtxt;
pub use coercion::can_coerce;
use fn_ctxt::FnCtxt;
use typeck_root_ctxt::TypeckRootCtxt;

use crate::check::check_fn;
use crate::coercion::DynamicCoerceMany;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::ops::Deref;
/// `bar()` will each have their own `FnCtxt`, but they will
/// share the inference context, will process obligations together,
/// can access each other's local types (scoping permitted), etc.
pub struct TypeckRootCtxt<'tcx> {
pub(crate) struct TypeckRootCtxt<'tcx> {
pub(super) infcx: InferCtxt<'tcx>,

pub(super) typeck_results: RefCell<ty::TypeckResults<'tcx>>,
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1337,8 +1337,9 @@ impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller {
}

declare_lint! {
/// The `unreachable_pub` lint triggers for `pub` items not reachable from
/// the crate root.
/// The `unreachable_pub` lint triggers for `pub` items not reachable from other crates - that
/// means neither directly accessible, nor reexported, nor leaked through things like return
/// types.
///
/// ### Example
///
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ declare_lint! {
/// This functionality was removed in #97346, but then rolled back in #99860
/// because it caused regressions.
///
/// We plan on reintroducing this as a hard error, but in the mean time,
/// We plan on reintroducing this as a hard error, but in the meantime,
/// this lint serves to warn and suggest fixes for any use-cases which rely
/// on this behavior.
///
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4311,7 +4311,6 @@ declare_lint! {
/// ### Example
///
/// ```rust,compile_fail
/// # #![feature(type_privacy_lints)]
/// # #![allow(unused)]
/// #![deny(unnameable_types)]
/// mod m {
Expand All @@ -4328,10 +4327,14 @@ declare_lint! {
///
/// It is often expected that if you can obtain an object of type `T`, then
/// you can name the type `T` as well, this lint attempts to enforce this rule.
/// The recommended action is to either reexport the type properly to make it nameable,
/// or document that users are not supposed to be able to name it for one reason or another.
///
/// Besides types, this lint applies to traits because traits can also leak through signatures,
/// and you may obtain objects of their `dyn Trait` or `impl Trait` types.
pub UNNAMEABLE_TYPES,
Allow,
"effective visibility of a type is larger than the area in which it can be named",
@feature_gate = sym::type_privacy_lints;
}

declare_lint! {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef Child, size_t *Size) {
Expected<StringRef> NameOrErr = Child->getName();
if (!NameOrErr) {
// rustc_codegen_llvm currently doesn't use this error string, but it might be
// useful in the future, and in the mean time this tells LLVM that the
// useful in the future, and in the meantime this tells LLVM that the
// error was not ignored and that it shouldn't abort the process.
LLVMRustSetLastError(toString(NameOrErr.takeError()).c_str());
return nullptr;
Expand Down
10 changes: 8 additions & 2 deletions library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1614,7 +1614,10 @@ impl<T, A: Allocator> VecDeque<T, A> {
let old_head = self.head;
self.head = self.to_physical_idx(1);
self.len -= 1;
Some(unsafe { self.buffer_read(old_head) })
unsafe {
core::hint::assert_unchecked(self.len < self.capacity());
Some(self.buffer_read(old_head))
}
}
}

Expand All @@ -1638,7 +1641,10 @@ impl<T, A: Allocator> VecDeque<T, A> {
None
} else {
self.len -= 1;
Some(unsafe { self.buffer_read(self.to_physical_idx(self.len)) })
unsafe {
core::hint::assert_unchecked(self.len < self.capacity());
Some(self.buffer_read(self.to_physical_idx(self.len)))
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion library/core/src/ops/try_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ pub trait FromResidual<R = <Self as Try>::Residual> {
/// This should be implemented consistently with the `branch` method such
/// that applying the `?` operator will get back an equivalent residual:
/// `FromResidual::from_residual(r).branch() --> ControlFlow::Break(r)`.
/// (It must not be an *identical* residual when interconversion is involved.)
/// (The residual is not mandated to be *identical* when interconversion is involved.)
///
/// # Examples
///
Expand Down
5 changes: 5 additions & 0 deletions library/std/src/sys/pal/hermit/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ impl FileDesc {
pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> {
unsupported()
}

pub fn fstat(&self, stat: *mut abi::stat) -> io::Result<()> {
cvt(unsafe { abi::fstat(self.fd.as_raw_fd(), stat) })?;
Ok(())
}
}

impl<'a> Read for &'a FileDesc {
Expand Down
Loading
Loading