Skip to content

Commit

Permalink
Auto merge of rust-lang#129540 - tgross35:rollup-y6iaujw, r=tgross35
Browse files Browse the repository at this point in the history
Rollup of 10 pull requests

Successful merges:

 - rust-lang#128467 (Detect `*` operator on `!Sized` expression)
 - rust-lang#128524 (Don't suggest turning crate-level attributes into outer style)
 - rust-lang#128735 (Add a special case for `CStr`/`CString` in the `improper_ctypes` lint)
 - rust-lang#129429 (Print the generic parameter along with the variance in dumps.)
 - rust-lang#129430 (rustdoc: show exact case-sensitive matches first)
 - rust-lang#129449 (Put Pin::as_deref_mut in impl Pin<Ptr> / rearrange Pin methods)
 - rust-lang#129481 (Update `compiler_builtins` to `0.1.121`)
 - rust-lang#129482 (Add myself to the review rotation for libs)
 - rust-lang#129492 (Make wasm32 platform support docs easier to read)
 - rust-lang#129512 (update the doc comment on lintchecker b/c it parses html now)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Aug 25, 2024
2 parents f167efa + 11ebb59 commit 697d953
Show file tree
Hide file tree
Showing 71 changed files with 687 additions and 303 deletions.
11 changes: 11 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2902,6 +2902,17 @@ pub struct AttrItem {
pub tokens: Option<LazyAttrTokenStream>,
}

impl AttrItem {
pub fn is_valid_for_outer_style(&self) -> bool {
self.path == sym::cfg_attr
|| self.path == sym::cfg
|| self.path == sym::forbid
|| self.path == sym::warn
|| self.path == sym::allow
|| self.path == sym::deny
}
}

/// `TraitRef`s appear in impls.
///
/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
Expand Down
32 changes: 24 additions & 8 deletions compiler/rustc_hir_analysis/src/variance/dump.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
use std::fmt::Write;

use rustc_hir::def::DefKind;
use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_middle::ty::TyCtxt;
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
use rustc_middle::ty::{GenericArgs, TyCtxt};
use rustc_span::symbol::sym;

fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
let variances = tcx.variances_of(def_id);
let generics = GenericArgs::identity_for_item(tcx, def_id);
// 7 = 2-letter parameter + ": " + 1-letter variance + ", "
let mut ret = String::with_capacity(2 + 7 * variances.len());
ret.push('[');
for (arg, variance) in generics.iter().zip(variances.iter()) {
write!(ret, "{arg}: {variance:?}, ").unwrap();
}
// Remove trailing `, `.
if !variances.is_empty() {
ret.pop();
ret.pop();
}
ret.push(']');
ret
}

pub(crate) fn variances(tcx: TyCtxt<'_>) {
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
for id in tcx.hir().items() {
let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };

let variances = tcx.variances_of(id.owner_id);

tcx.dcx().emit_err(crate::errors::VariancesOf {
span: tcx.def_span(id.owner_id),
variances: format!("{variances:?}"),
variances: format_variances(tcx, id.owner_id.def_id),
});
}
}
Expand All @@ -22,11 +40,9 @@ pub(crate) fn variances(tcx: TyCtxt<'_>) {
continue;
}

let variances = tcx.variances_of(id.owner_id);

tcx.dcx().emit_err(crate::errors::VariancesOf {
span: tcx.def_span(id.owner_id),
variances: format!("{variances:?}"),
variances: format_variances(tcx, id.owner_id.def_id),
});
}
}
6 changes: 5 additions & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -841,13 +841,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ret_ty = ret_coercion.borrow().expected_ty();
let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty);
let mut span = return_expr.span;
let mut hir_id = return_expr.hir_id;
// Use the span of the trailing expression for our cause,
// not the span of the entire function
if !explicit_return
&& let ExprKind::Block(body, _) = return_expr.kind
&& let Some(last_expr) = body.expr
{
span = last_expr.span;
hir_id = last_expr.hir_id;
}
ret_coercion.borrow_mut().coerce(
self,
Expand All @@ -864,6 +866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.select_obligations_where_possible(|errors| {
self.point_at_return_for_opaque_ty_error(
errors,
hir_id,
span,
return_expr_ty,
return_expr.span,
Expand Down Expand Up @@ -921,6 +924,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn point_at_return_for_opaque_ty_error(
&self,
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
hir_id: HirId,
span: Span,
return_expr_ty: Ty<'tcx>,
return_span: Span,
Expand All @@ -935,7 +939,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let new_cause = ObligationCause::new(
cause.span,
cause.body_id,
ObligationCauseCode::OpaqueReturnType(Some((return_expr_ty, span))),
ObligationCauseCode::OpaqueReturnType(Some((return_expr_ty, hir_id))),
);
*cause = new_cause;
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,11 @@ lint_improper_ctypes_box = box cannot be represented as a single pointer
lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
lint_improper_ctypes_char_reason = the `char` type has no C equivalent
lint_improper_ctypes_cstr_help =
consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
lint_improper_ctypes_cstr_reason = `CStr`/`CString` do not have a guaranteed layout
lint_improper_ctypes_dyn = trait objects have no C equivalent
lint_improper_ctypes_enum_repr_help =
Expand Down
54 changes: 39 additions & 15 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,14 @@ struct ImproperCTypesVisitor<'a, 'tcx> {
mode: CItemKind,
}

/// Accumulator for recursive ffi type checking
struct CTypesVisitorState<'tcx> {
cache: FxHashSet<Ty<'tcx>>,
/// The original type being checked, before we recursed
/// to any other types it contains.
base_ty: Ty<'tcx>,
}

enum FfiResult<'tcx> {
FfiSafe,
FfiPhantom(Ty<'tcx>),
Expand Down Expand Up @@ -1213,7 +1221,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
/// Checks if the given field's type is "ffi-safe".
fn check_field_type_for_ffi(
&self,
cache: &mut FxHashSet<Ty<'tcx>>,
acc: &mut CTypesVisitorState<'tcx>,
field: &ty::FieldDef,
args: GenericArgsRef<'tcx>,
) -> FfiResult<'tcx> {
Expand All @@ -1223,13 +1231,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
.tcx
.try_normalize_erasing_regions(self.cx.param_env, field_ty)
.unwrap_or(field_ty);
self.check_type_for_ffi(cache, field_ty)
self.check_type_for_ffi(acc, field_ty)
}

/// Checks if the given `VariantDef`'s field types are "ffi-safe".
fn check_variant_for_ffi(
&self,
cache: &mut FxHashSet<Ty<'tcx>>,
acc: &mut CTypesVisitorState<'tcx>,
ty: Ty<'tcx>,
def: ty::AdtDef<'tcx>,
variant: &ty::VariantDef,
Expand All @@ -1239,7 +1247,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
let transparent_with_all_zst_fields = if def.repr().transparent() {
if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
// Transparent newtypes have at most one non-ZST field which needs to be checked..
match self.check_field_type_for_ffi(cache, field, args) {
match self.check_field_type_for_ffi(acc, field, args) {
FfiUnsafe { ty, .. } if ty.is_unit() => (),
r => return r,
}
Expand All @@ -1257,7 +1265,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
// We can't completely trust `repr(C)` markings, so make sure the fields are actually safe.
let mut all_phantom = !variant.fields.is_empty();
for field in &variant.fields {
all_phantom &= match self.check_field_type_for_ffi(cache, field, args) {
all_phantom &= match self.check_field_type_for_ffi(acc, field, args) {
FfiSafe => false,
// `()` fields are FFI-safe!
FfiUnsafe { ty, .. } if ty.is_unit() => false,
Expand All @@ -1277,7 +1285,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {

/// Checks if the given type is "ffi-safe" (has a stable, well-defined
/// representation which can be exported to C code).
fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> FfiResult<'tcx> {
fn check_type_for_ffi(
&self,
acc: &mut CTypesVisitorState<'tcx>,
ty: Ty<'tcx>,
) -> FfiResult<'tcx> {
use FfiResult::*;

let tcx = self.cx.tcx;
Expand All @@ -1286,7 +1298,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
// `struct S(*mut S);`.
// FIXME: A recursion limit is necessary as well, for irregular
// recursive types.
if !cache.insert(ty) {
if !acc.cache.insert(ty) {
return FfiSafe;
}

Expand All @@ -1308,6 +1320,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
}
match def.adt_kind() {
AdtKind::Struct | AdtKind::Union => {
if let Some(sym::cstring_type | sym::cstr_type) =
tcx.get_diagnostic_name(def.did())
&& !acc.base_ty.is_mutable_ptr()
{
return FfiUnsafe {
ty,
reason: fluent::lint_improper_ctypes_cstr_reason,
help: Some(fluent::lint_improper_ctypes_cstr_help),
};
}

if !def.repr().c() && !def.repr().transparent() {
return FfiUnsafe {
ty,
Expand Down Expand Up @@ -1354,7 +1377,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
};
}

self.check_variant_for_ffi(cache, ty, def, def.non_enum_variant(), args)
self.check_variant_for_ffi(acc, ty, def, def.non_enum_variant(), args)
}
AdtKind::Enum => {
if def.variants().is_empty() {
Expand All @@ -1378,7 +1401,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
if let Some(ty) =
repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode)
{
return self.check_type_for_ffi(cache, ty);
return self.check_type_for_ffi(acc, ty);
}

return FfiUnsafe {
Expand All @@ -1399,7 +1422,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
};
}

match self.check_variant_for_ffi(cache, ty, def, variant, args) {
match self.check_variant_for_ffi(acc, ty, def, variant, args) {
FfiSafe => (),
r => return r,
}
Expand Down Expand Up @@ -1469,9 +1492,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
FfiSafe
}

ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => self.check_type_for_ffi(cache, ty),
ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => self.check_type_for_ffi(acc, ty),

ty::Array(inner_ty, _) => self.check_type_for_ffi(cache, inner_ty),
ty::Array(inner_ty, _) => self.check_type_for_ffi(acc, inner_ty),

ty::FnPtr(sig_tys, hdr) => {
let sig = sig_tys.with(hdr);
Expand All @@ -1485,7 +1508,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {

let sig = tcx.instantiate_bound_regions_with_erased(sig);
for arg in sig.inputs() {
match self.check_type_for_ffi(cache, *arg) {
match self.check_type_for_ffi(acc, *arg) {
FfiSafe => {}
r => return r,
}
Expand All @@ -1496,7 +1519,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
return FfiSafe;
}

self.check_type_for_ffi(cache, ret_ty)
self.check_type_for_ffi(acc, ret_ty)
}

ty::Foreign(..) => FfiSafe,
Expand Down Expand Up @@ -1619,7 +1642,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
return;
}

match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
let mut acc = CTypesVisitorState { cache: FxHashSet::default(), base_ty: ty };
match self.check_type_for_ffi(&mut acc, ty) {
FfiResult::FfiSafe => {}
FfiResult::FfiPhantom(ty) => {
self.emit_ffi_unsafe_type_lint(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ pub enum ObligationCauseCode<'tcx> {
ReturnValue(HirId),

/// Opaque return type of this function
OpaqueReturnType(Option<(Ty<'tcx>, Span)>),
OpaqueReturnType(Option<(Ty<'tcx>, HirId)>),

/// Block implicit return
BlockTailExpression(HirId, hir::MatchSource),
Expand Down
38 changes: 26 additions & 12 deletions compiler/rustc_parse/src/parser/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl<'a> Parser<'a> {
token::CommentKind::Line => OuterAttributeType::DocComment,
token::CommentKind::Block => OuterAttributeType::DocBlockComment,
},
true,
) {
err.note(fluent::parse_note);
err.span_suggestion_verbose(
Expand Down Expand Up @@ -139,7 +140,11 @@ impl<'a> Parser<'a> {

// Emit error if inner attribute is encountered and forbidden.
if style == ast::AttrStyle::Inner {
this.error_on_forbidden_inner_attr(attr_sp, inner_parse_policy);
this.error_on_forbidden_inner_attr(
attr_sp,
inner_parse_policy,
item.is_valid_for_outer_style(),
);
}

Ok(attr::mk_attr_from_item(&self.psess.attr_id_generator, item, None, style, attr_sp))
Expand All @@ -151,6 +156,7 @@ impl<'a> Parser<'a> {
err: &mut Diag<'_>,
span: Span,
attr_type: OuterAttributeType,
suggest_to_outer: bool,
) -> Option<Span> {
let mut snapshot = self.create_snapshot_for_diagnostic();
let lo = span.lo()
Expand Down Expand Up @@ -185,16 +191,18 @@ impl<'a> Parser<'a> {
// FIXME(#100717)
err.arg("item", item.kind.descr());
err.span_label(item.span, fluent::parse_label_does_not_annotate_this);
err.span_suggestion_verbose(
replacement_span,
fluent::parse_sugg_change_inner_to_outer,
match attr_type {
OuterAttributeType::Attribute => "",
OuterAttributeType::DocBlockComment => "*",
OuterAttributeType::DocComment => "/",
},
rustc_errors::Applicability::MachineApplicable,
);
if suggest_to_outer {
err.span_suggestion_verbose(
replacement_span,
fluent::parse_sugg_change_inner_to_outer,
match attr_type {
OuterAttributeType::Attribute => "",
OuterAttributeType::DocBlockComment => "*",
OuterAttributeType::DocComment => "/",
},
rustc_errors::Applicability::MachineApplicable,
);
}
return None;
}
Err(item_err) => {
Expand All @@ -205,7 +213,12 @@ impl<'a> Parser<'a> {
Some(replacement_span)
}

pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy) {
pub(super) fn error_on_forbidden_inner_attr(
&self,
attr_sp: Span,
policy: InnerAttrPolicy,
suggest_to_outer: bool,
) {
if let InnerAttrPolicy::Forbidden(reason) = policy {
let mut diag = match reason.as_ref().copied() {
Some(InnerAttrForbiddenReason::AfterOuterDocComment { prev_doc_comment_span }) => {
Expand Down Expand Up @@ -239,6 +252,7 @@ impl<'a> Parser<'a> {
&mut diag,
attr_sp,
OuterAttributeType::Attribute,
suggest_to_outer,
)
.is_some()
{
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,11 +459,16 @@ impl<'a> Parser<'a> {
pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
let (attrs, block) = self.parse_inner_attrs_and_block()?;
if let [.., last] = &*attrs {
let suggest_to_outer = match &last.kind {
ast::AttrKind::Normal(attr) => attr.item.is_valid_for_outer_style(),
_ => false,
};
self.error_on_forbidden_inner_attr(
last.span,
super::attr::InnerAttrPolicy::Forbidden(Some(
InnerAttrForbiddenReason::InCodeBlock,
)),
suggest_to_outer,
);
}
Ok(block)
Expand Down
Loading

0 comments on commit 697d953

Please sign in to comment.