Auto merge of #133978 - matthiaskrgr:rollup-6gh1iho, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #130209 (Stabilize `std::io::ErrorKind::CrossesDevices`) - #130254 (Stabilize `std::io::ErrorKind::QuotaExceeded`) - #132187 (Add Extend impls for tuples of arity 1 through 12) - #133875 (handle `--json-output` properly) - #133934 (Do not implement unsafe auto traits for types with unsafe fields) - #133954 (Hide errors whose suggestions would contain error constants or types) - #133960 (rustdoc: remove eq for clean::Attributes) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
9c707a8b76
32 changed files with 295 additions and 236 deletions
|
@ -998,6 +998,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
self.lower_const_arg(ct, FeedConstTy::No).into()
|
||||
}
|
||||
};
|
||||
if term.references_error() {
|
||||
continue;
|
||||
}
|
||||
// FIXME(#97583): This isn't syntactically well-formed!
|
||||
where_bounds.push(format!(
|
||||
" T: {trait}::{assoc_name} = {term}",
|
||||
|
|
|
@ -585,6 +585,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
self.trait_def(trait_def_id).implement_via_object
|
||||
}
|
||||
|
||||
fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
|
||||
self.trait_def(trait_def_id).safety == hir::Safety::Unsafe
|
||||
}
|
||||
|
||||
fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
|
||||
self.is_impl_trait_in_trait(def_id)
|
||||
}
|
||||
|
|
|
@ -978,6 +978,14 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||
fn async_destructor_ty(self, interner: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
self.async_destructor_ty(interner)
|
||||
}
|
||||
|
||||
fn has_unsafe_fields(self) -> bool {
|
||||
if let ty::Adt(adt_def, ..) = self.kind() {
|
||||
adt_def.all_fields().any(|x| x.safety == hir::Safety::Unsafe)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Type utilities
|
||||
|
|
|
@ -2,7 +2,7 @@ use rustc_ast as ast;
|
|||
use rustc_hir::LangItem;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
|
||||
use rustc_middle::ty::{self, ScalarInt, TyCtxt};
|
||||
use rustc_middle::ty::{self, ScalarInt, TyCtxt, TypeVisitableExt as _};
|
||||
use tracing::trace;
|
||||
|
||||
use crate::build::parse_float_into_scalar;
|
||||
|
@ -13,6 +13,10 @@ pub(crate) fn lit_to_const<'tcx>(
|
|||
) -> Result<ty::Const<'tcx>, LitToConstError> {
|
||||
let LitToConstInput { lit, ty, neg } = lit_input;
|
||||
|
||||
if let Err(guar) = ty.error_reported() {
|
||||
return Ok(ty::Const::new_error(tcx, guar));
|
||||
}
|
||||
|
||||
let trunc = |n| {
|
||||
let width = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) {
|
||||
Ok(layout) => layout.size,
|
||||
|
|
|
@ -169,6 +169,14 @@ where
|
|||
return result;
|
||||
}
|
||||
|
||||
// Only consider auto impls of unsafe traits when there are no unsafe
|
||||
// fields.
|
||||
if ecx.cx().trait_is_unsafe(goal.predicate.def_id())
|
||||
&& goal.predicate.self_ty().has_unsafe_fields()
|
||||
{
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
// We only look into opaque types during analysis for opaque types
|
||||
// outside of their defining scope. Doing so for opaques in the
|
||||
// defining scope may require calling `typeck` on the same item we're
|
||||
|
|
|
@ -18,6 +18,7 @@ use rustc_infer::traits::{
|
|||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt, TypingMode};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_type_ir::Interner;
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
use super::SelectionCandidate::*;
|
||||
|
@ -794,6 +795,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
| ty::CoroutineWitness(..) => {
|
||||
use rustc_type_ir::inherent::*;
|
||||
|
||||
// Only consider auto impls of unsafe traits when there are
|
||||
// no unsafe fields.
|
||||
if self.tcx().trait_is_unsafe(def_id) && self_ty.has_unsafe_fields() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only consider auto impls if there are no manual impls for the root of `self_ty`.
|
||||
//
|
||||
// For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
|
||||
|
|
|
@ -136,6 +136,9 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
|||
matches!(self.kind(), ty::FnPtr(..))
|
||||
}
|
||||
|
||||
/// Checks whether this type is an ADT that has unsafe fields.
|
||||
fn has_unsafe_fields(self) -> bool;
|
||||
|
||||
fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
|
||||
match self.kind() {
|
||||
ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
|
||||
|
|
|
@ -270,6 +270,9 @@ pub trait Interner:
|
|||
|
||||
fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool;
|
||||
|
||||
/// Returns `true` if this is an `unsafe trait`.
|
||||
fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool;
|
||||
|
||||
fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool;
|
||||
|
||||
fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue