Auto merge of #129540 - tgross35:rollup-y6iaujw, r=tgross35

Rollup of 10 pull requests

Successful merges:

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

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-08-25 05:45:02 +00:00
commit 697d9530d7
71 changed files with 687 additions and 303 deletions

View File

@ -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

View File

@ -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),
});
}
}
@ -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),
});
}
}

View File

@ -841,6 +841,7 @@ 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
@ -848,6 +849,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let Some(last_expr) = body.expr
{
span = last_expr.span;
hir_id = last_expr.hir_id;
}
ret_coercion.borrow_mut().coerce(
self,
@ -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,
@ -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,
@ -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;
}

View File

@ -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 =

View File

@ -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>),
@ -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> {
@ -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,
@ -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,
}
@ -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,
@ -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;
@ -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;
}
@ -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,
@ -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() {
@ -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 {
@ -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,
}
@ -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);
@ -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,
}
@ -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,
@ -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(

View File

@ -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),

View File

@ -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(
@ -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))
@ -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()
@ -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) => {
@ -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 }) => {
@ -239,6 +252,7 @@ impl<'a> Parser<'a> {
&mut diag,
attr_sp,
OuterAttributeType::Attribute,
suggest_to_outer,
)
.is_some()
{

View File

@ -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)

View File

@ -673,6 +673,7 @@ symbols! {
crate_visibility_modifier,
crt_dash_static: "crt-static",
csky_target_feature,
cstr_type,
cstring_type,
ctlz,
ctlz_nonzero,

View File

@ -2727,6 +2727,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let tcx = self.tcx;
let predicate = predicate.upcast(tcx);
let suggest_remove_deref = |err: &mut Diag<'_, G>, expr: &hir::Expr<'_>| {
if let Some(pred) = predicate.as_trait_clause()
&& tcx.is_lang_item(pred.def_id(), LangItem::Sized)
&& let hir::ExprKind::Unary(hir::UnOp::Deref, inner) = expr.kind
{
err.span_suggestion_verbose(
expr.span.until(inner.span),
"references are always `Sized`, even if they point to unsized data; consider \
not dereferencing the expression",
String::new(),
Applicability::MaybeIncorrect,
);
}
};
match *cause_code {
ObligationCauseCode::ExprAssignable
| ObligationCauseCode::MatchExpressionArm { .. }
@ -2773,6 +2787,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
| ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)
if !span.is_dummy() =>
{
if let ObligationCauseCode::WhereClauseInExpr(_, _, hir_id, pos) = &cause_code {
if let Node::Expr(expr) = tcx.parent_hir_node(*hir_id)
&& let hir::ExprKind::Call(_, args) = expr.kind
&& let Some(expr) = args.get(*pos)
{
suggest_remove_deref(err, &expr);
} else if let Node::Expr(expr) = self.tcx.hir_node(*hir_id)
&& let hir::ExprKind::MethodCall(_, _, args, _) = expr.kind
&& let Some(expr) = args.get(*pos)
{
suggest_remove_deref(err, &expr);
}
}
let item_name = tcx.def_path_str(item_def_id);
let short_item_name = with_forced_trimmed_paths!(tcx.def_path_str(item_def_id));
let mut multispan = MultiSpan::from(span);
@ -2970,6 +2997,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
));
err.downgrade_to_delayed_bug();
}
let mut local = true;
match tcx.parent_hir_node(hir_id) {
Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }) => {
err.span_suggestion_verbose(
@ -2978,7 +3006,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
"&",
Applicability::MachineApplicable,
);
err.note("all local variables must have a statically known size");
}
Node::LetStmt(hir::LetStmt {
init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }),
@ -2993,7 +3020,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
"&",
Applicability::MachineApplicable,
);
err.note("all local variables must have a statically known size");
}
Node::LetStmt(hir::LetStmt { init: Some(expr), .. }) => {
// When encountering an assignment of an unsized trait, like `let x = *"";`,
// we check if the RHS is a deref operation, to suggest removing it.
suggest_remove_deref(err, &expr);
}
Node::Param(param) => {
err.span_suggestion_verbose(
@ -3003,10 +3034,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
"&",
Applicability::MachineApplicable,
);
local = false;
}
_ => {
err.note("all local variables must have a statically known size");
}
_ => {}
}
if local {
err.note("all local variables must have a statically known size");
}
if !tcx.features().unsized_locals {
err.help("unsized locals are gated as an unstable feature");
@ -3529,14 +3562,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
);
}
ObligationCauseCode::OpaqueReturnType(expr_info) => {
if let Some((expr_ty, expr_span)) = expr_info {
if let Some((expr_ty, hir_id)) = expr_info {
let expr_ty = self.tcx.short_ty_string(expr_ty, &mut long_ty_file);
let expr = self.infcx.tcx.hir().expect_expr(hir_id);
err.span_label(
expr_span,
expr.span,
with_forced_trimmed_paths!(format!(
"return type was inferred to be `{expr_ty}` here",
)),
);
suggest_remove_deref(err, &expr);
}
}
}

View File

@ -58,9 +58,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
version = "0.1.120"
version = "0.1.121"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38c44e9c76d996d8049dee591a997eab801069ad86ed892ed3039f68b73d301c"
checksum = "ce956e6dc07082ec481f0935a51e83b343f8ca51be560452c0ebf830d0bdf5a5"
dependencies = [
"cc",
"rustc-std-workspace-core",

View File

@ -10,7 +10,7 @@ edition = "2021"
[dependencies]
core = { path = "../core" }
compiler_builtins = { version = "0.1.120", features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "0.1.121", features = ['rustc-dep-of-std'] }
[dev-dependencies]
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }

View File

@ -91,6 +91,7 @@ use crate::{fmt, intrinsics, ops, slice, str};
/// [str]: prim@str "str"
#[derive(PartialEq, Eq, Hash)]
#[stable(feature = "core_c_str", since = "1.64.0")]
#[rustc_diagnostic_item = "cstr_type"]
#[rustc_has_incoherent_inherent_impls]
#[lang = "CStr"]
// `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies

View File

@ -1291,8 +1291,8 @@ impl<Ptr: Deref> Pin<Ptr> {
/// // Now, if `x` was the only reference, we have a mutable reference to
/// // data that we pinned above, which we could use to move it as we have
/// // seen in the previous example. We have violated the pinning API contract.
/// }
/// ```
/// }
/// ```
///
/// ## Pinning of closure captures
///
@ -1370,33 +1370,6 @@ impl<Ptr: Deref> Pin<Ptr> {
unsafe { Pin::new_unchecked(&*self.__pointer) }
}
/// Unwraps this `Pin<Ptr>`, returning the underlying `Ptr`.
///
/// # Safety
///
/// This function is unsafe. You must guarantee that you will continue to
/// treat the pointer `Ptr` as pinned after you call this function, so that
/// the invariants on the `Pin` type can be upheld. If the code using the
/// resulting `Ptr` does not continue to maintain the pinning invariants that
/// is a violation of the API contract and may lead to undefined behavior in
/// later (safe) operations.
///
/// Note that you must be able to guarantee that the data pointed to by `Ptr`
/// will be treated as pinned all the way until its `drop` handler is complete!
///
/// *For more information, see the [`pin` module docs][self]*
///
/// If the underlying data is [`Unpin`], [`Pin::into_inner`] should be used
/// instead.
#[inline(always)]
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
#[stable(feature = "pin_into_inner", since = "1.39.0")]
pub const unsafe fn into_inner_unchecked(pin: Pin<Ptr>) -> Ptr {
pin.__pointer
}
}
impl<Ptr: DerefMut> Pin<Ptr> {
/// Gets a mutable reference to the pinned value this `Pin<Ptr>` points to.
///
/// This is a generic method to go from `&mut Pin<Pointer<T>>` to `Pin<&mut T>`.
@ -1428,11 +1401,55 @@ impl<Ptr: DerefMut> Pin<Ptr> {
/// ```
#[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target> {
pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target>
where
Ptr: DerefMut,
{
// SAFETY: see documentation on this function
unsafe { Pin::new_unchecked(&mut *self.__pointer) }
}
/// Gets `Pin<&mut T>` to the underlying pinned value from this nested `Pin`-pointer.
///
/// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
/// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
/// move in the future, and this method does not enable the pointee to move. "Malicious"
/// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of
/// `Pin::new_unchecked`.
#[unstable(feature = "pin_deref_mut", issue = "86918")]
#[must_use = "`self` will be dropped if the result is not used"]
#[inline(always)]
pub fn as_deref_mut(self: Pin<&mut Pin<Ptr>>) -> Pin<&mut Ptr::Target>
where
Ptr: DerefMut,
{
// SAFETY: What we're asserting here is that going from
//
// Pin<&mut Pin<Ptr>>
//
// to
//
// Pin<&mut Ptr::Target>
//
// is safe.
//
// We need to ensure that two things hold for that to be the case:
//
// 1) Once we give out a `Pin<&mut Ptr::Target>`, a `&mut Ptr::Target` will not be given out.
// 2) By giving out a `Pin<&mut Ptr::Target>`, we do not risk violating
// `Pin<&mut Pin<Ptr>>`
//
// The existence of `Pin<Ptr>` is sufficient to guarantee #1: since we already have a
// `Pin<Ptr>`, it must already uphold the pinning guarantees, which must mean that
// `Pin<&mut Ptr::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
// on the fact that `Ptr` is _also_ pinned.
//
// For #2, we need to ensure that code given a `Pin<&mut Ptr::Target>` cannot cause the
// `Pin<Ptr>` to move? That is not possible, since `Pin<&mut Ptr::Target>` no longer retains
// any access to the `Ptr` itself, much less the `Pin<Ptr>`.
unsafe { self.get_unchecked_mut() }.as_mut()
}
/// Assigns a new value to the memory location pointed to by the `Pin<Ptr>`.
///
/// This overwrites pinned data, but that is okay: the original pinned value's destructor gets
@ -1457,10 +1474,36 @@ impl<Ptr: DerefMut> Pin<Ptr> {
#[inline(always)]
pub fn set(&mut self, value: Ptr::Target)
where
Ptr: DerefMut,
Ptr::Target: Sized,
{
*(self.__pointer) = value;
}
/// Unwraps this `Pin<Ptr>`, returning the underlying `Ptr`.
///
/// # Safety
///
/// This function is unsafe. You must guarantee that you will continue to
/// treat the pointer `Ptr` as pinned after you call this function, so that
/// the invariants on the `Pin` type can be upheld. If the code using the
/// resulting `Ptr` does not continue to maintain the pinning invariants that
/// is a violation of the API contract and may lead to undefined behavior in
/// later (safe) operations.
///
/// Note that you must be able to guarantee that the data pointed to by `Ptr`
/// will be treated as pinned all the way until its `drop` handler is complete!
///
/// *For more information, see the [`pin` module docs][self]*
///
/// If the underlying data is [`Unpin`], [`Pin::into_inner`] should be used
/// instead.
#[inline(always)]
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
#[stable(feature = "pin_into_inner", since = "1.39.0")]
pub const unsafe fn into_inner_unchecked(pin: Pin<Ptr>) -> Ptr {
pin.__pointer
}
}
impl<'a, T: ?Sized> Pin<&'a T> {
@ -1613,46 +1656,6 @@ impl<T: ?Sized> Pin<&'static T> {
}
}
impl<'a, Ptr: DerefMut> Pin<&'a mut Pin<Ptr>> {
/// Gets `Pin<&mut T>` to the underlying pinned value from this nested `Pin`-pointer.
///
/// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
/// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
/// move in the future, and this method does not enable the pointee to move. "Malicious"
/// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of
/// `Pin::new_unchecked`.
#[unstable(feature = "pin_deref_mut", issue = "86918")]
#[must_use = "`self` will be dropped if the result is not used"]
#[inline(always)]
pub fn as_deref_mut(self) -> Pin<&'a mut Ptr::Target> {
// SAFETY: What we're asserting here is that going from
//
// Pin<&mut Pin<Ptr>>
//
// to
//
// Pin<&mut Ptr::Target>
//
// is safe.
//
// We need to ensure that two things hold for that to be the case:
//
// 1) Once we give out a `Pin<&mut Ptr::Target>`, a `&mut Ptr::Target` will not be given out.
// 2) By giving out a `Pin<&mut Ptr::Target>`, we do not risk violating
// `Pin<&mut Pin<Ptr>>`
//
// The existence of `Pin<Ptr>` is sufficient to guarantee #1: since we already have a
// `Pin<Ptr>`, it must already uphold the pinning guarantees, which must mean that
// `Pin<&mut Ptr::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
// on the fact that `Ptr` is _also_ pinned.
//
// For #2, we need to ensure that code given a `Pin<&mut Ptr::Target>` cannot cause the
// `Pin<Ptr>` to move? That is not possible, since `Pin<&mut Ptr::Target>` no longer retains
// any access to the `Ptr` itself, much less the `Pin<Ptr>`.
unsafe { self.get_unchecked_mut() }.as_mut()
}
}
impl<T: ?Sized> Pin<&'static mut T> {
/// Gets a pinning mutable reference from a static mutable reference.
///

View File

@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core", public = true }
compiler_builtins = { version = "0.1.120" }
compiler_builtins = { version = "0.1.121" }
profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" }
hashbrown = { version = "0.14", default-features = false, features = [

View File

@ -29,11 +29,10 @@ that not all uses of `wasm32-unknown-unknown` are using JavaScript and the web.
## Target maintainers
When this target was added to the compiler platform-specific documentation here
When this target was added to the compiler, platform-specific documentation here
was not maintained at that time. This means that the list below is not
exhaustive and there are more interested parties in this target. That being
said since when this document was last updated those interested in maintaining
this target are:
exhaustive, and there are more interested parties in this target. That being
said, those interested in maintaining this target are:
- Alex Crichton, https://github.com/alexcrichton

View File

@ -1393,6 +1393,7 @@ function initSearch(rawSearchIndex) {
*/
async function sortResults(results, isType, preferredCrate) {
const userQuery = parsedQuery.userQuery;
const casedUserQuery = parsedQuery.original;
const result_list = [];
for (const result of results.values()) {
result.item = searchIndex[result.id];
@ -1403,6 +1404,13 @@ function initSearch(rawSearchIndex) {
result_list.sort((aaa, bbb) => {
let a, b;
// sort by exact case-sensitive match
a = (aaa.item.name !== casedUserQuery);
b = (bbb.item.name !== casedUserQuery);
if (a !== b) {
return a - b;
}
// sort by exact match with regard to the last word (mismatch goes later)
a = (aaa.word !== userQuery);
b = (bbb.word !== userQuery);

View File

@ -6,8 +6,10 @@
//! script is to check all relative links in our documentation to make sure they
//! actually point to a valid place.
//!
//! Currently this doesn't actually do any HTML parsing or anything fancy like
//! that, it just has a simple "regex" to search for `href` and `id` tags.
//! Currently uses a combination of HTML parsing to
//! extract the `href` and `id` attributes,
//! and regex search on the orignal markdown to handle intra-doc links.
//!
//! These values are then translated to file URLs if possible and then the
//! destination is asserted to exist.
//!

View File

@ -0,0 +1,7 @@
const EXPECTED = {
'query': 'Copy',
'others': [
{ 'path': 'std::marker', 'name': 'Copy' },
{ 'path': 'std::fs', 'name': 'copy' },
],
}

View File

@ -8,11 +8,6 @@ LL | fn main() {}
| ------------ the inner attribute doesn't annotate this function
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
help: to annotate the function, change the attribute from inner to outer style
|
LL - reuse a as b { #![rustc_dummy] self }
LL + reuse a as b { #[rustc_dummy] self }
|
error: aborting due to 1 previous error

View File

@ -9,6 +9,11 @@ LL | let _x: Box<str> = Box::new(*"hello world");
= help: the trait `Sized` is not implemented for `str`
note: required by a bound in `Box::<T>::new`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - let _x: Box<str> = Box::new(*"hello world");
LL + let _x: Box<str> = Box::new("hello world");
|
error[E0277]: the size for values of type `[isize]` cannot be known at compilation time
--> $DIR/dst-rvalue.rs:8:37
@ -21,6 +26,11 @@ LL | let _x: Box<[isize]> = Box::new(*array);
= help: the trait `Sized` is not implemented for `[isize]`
note: required by a bound in `Box::<T>::new`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - let _x: Box<[isize]> = Box::new(*array);
LL + let _x: Box<[isize]> = Box::new(array);
|
error: aborting due to 2 previous errors

View File

@ -1,7 +1,7 @@
#![feature(rustc_attrs)]
#[rustc_variance]
struct Foo<'a, T> { //~ ERROR [+, o]
struct Foo<'a, T> { //~ ERROR ['a: +, T: o]
t: &'a mut T,
}

View File

@ -1,4 +1,4 @@
error: [+, o]
error: ['a: +, T: o]
--> $DIR/E0208.rs:4:1
|
LL | struct Foo<'a, T> {

View File

@ -1,21 +1,21 @@
warning: `extern` fn uses type `[i8 or u8 (arch dependant)]`, which is not FFI-safe
warning: `extern` fn uses type `CStr`, which is not FFI-safe
--> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:7:12
|
LL | type Foo = extern "C" fn(::std::ffi::CStr);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider using a raw pointer instead
= note: slices have no C equivalent
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
= note: `#[warn(improper_ctypes_definitions)]` on by default
warning: `extern` block uses type `[i8 or u8 (arch dependant)]`, which is not FFI-safe
warning: `extern` block uses type `CStr`, which is not FFI-safe
--> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:10:18
|
LL | fn meh(blah: Foo);
| ^^^ not FFI-safe
|
= help: consider using a raw pointer instead
= note: slices have no C equivalent
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
= note: `#[warn(improper_ctypes)]` on by default
warning: 2 warnings emitted

View File

@ -6,13 +6,13 @@ trait Bar<'a> {
}
fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> {
//~^ ERROR [o, o]
//~^ ERROR ['a: o, T: o]
// captures both T and 'a invariantly
()
}
fn foo2<'a, T: Bar<'a>>() -> impl Into<T::Assoc> + 'a {
//~^ ERROR [o, o, o]
//~^ ERROR ['a: o, T: o, 'a: o]
// captures both T and 'a invariantly, and also duplicates `'a`
// i.e. the opaque looks like `impl Into<<T as Bar<'a>>::Assoc> + 'a_duplicated`
()

View File

@ -1,10 +1,10 @@
error: [o, o]
error: ['a: o, T: o]
--> $DIR/capture-lifetime-not-in-hir.rs:8:29
|
LL | fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> {
| ^^^^^^^^^^^^^^^^^^^
error: [o, o, o]
error: ['a: o, T: o, 'a: o]
--> $DIR/capture-lifetime-not-in-hir.rs:14:30
|
LL | fn foo2<'a, T: Bar<'a>>() -> impl Into<T::Assoc> + 'a {

View File

@ -10,7 +10,7 @@ note: lifetime declared here
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
| ^^
error: [o]
error: ['a: o]
--> $DIR/implicit-capture-late.rs:10:55
|
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {

View File

@ -7,14 +7,16 @@ impl<T> Captures<'_> for T {}
trait Foo<'i> {
fn implicit_capture_early<'a: 'a>() -> impl Sized {}
//~^ [o, *, *, o, o]
// Self, 'i, 'a, 'i_duplicated, 'a_duplicated
//~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [o, *, *, o, o]
fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
//~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {} //~ [o, *, o, o]
fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
//~^ [Self: o, 'i: *, 'a: o, 'i: o]
fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o, *, o, o]
fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
//~^ [Self: o, 'i: *, 'a: o, 'i: o]
}
fn main() {}

View File

@ -1,23 +1,23 @@
error: [o, *, *, o, o]
error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:9:44
|
LL | fn implicit_capture_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: [o, *, *, o, o]
--> $DIR/variance.rs:13:44
error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:12:44
|
LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, *, o, o]
error: [Self: o, 'i: *, 'a: o, 'i: o]
--> $DIR/variance.rs:15:48
|
LL | fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: [o, *, o, o]
--> $DIR/variance.rs:17:48
error: [Self: o, 'i: *, 'a: o, 'i: o]
--> $DIR/variance.rs:18:48
|
LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,22 +1,22 @@
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:14:36
|
LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:19:32
|
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o]
error: ['a: o]
--> $DIR/variance.rs:21:40
|
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: [o]
error: ['a: o]
--> $DIR/variance.rs:26:36
|
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}

View File

@ -1,22 +1,22 @@
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:14:36
|
LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:19:32
|
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o]
error: ['a: o]
--> $DIR/variance.rs:21:40
|
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: [o]
error: ['a: o]
--> $DIR/variance.rs:26:36
|
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}

View File

@ -1,10 +1,10 @@
error: [*]
error: ['a: *]
--> $DIR/variance.rs:14:36
|
LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:19:32
|
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
@ -16,7 +16,7 @@ error: []
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: [o]
error: ['a: o]
--> $DIR/variance.rs:26:36
|
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}

View File

@ -12,17 +12,17 @@ trait Captures<'a> {}
impl<T> Captures<'_> for T {}
fn not_captured_early<'a: 'a>() -> impl Sized {}
//[old]~^ [*]
//[new]~^^ [*, o]
//[e2024]~^^^ [*, o]
//[old]~^ ['a: *]
//[new]~^^ ['a: *, 'a: o]
//[e2024]~^^^ ['a: *, 'a: o]
fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [*, o]
fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ ['a: *, 'a: o]
fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
//[old]~^ []
//[new]~^^ [o]
//[e2024]~^^^ [o]
//[new]~^^ ['a: o]
//[e2024]~^^^ ['a: o]
fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o]
fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ ['a: o]
fn main() {}

View File

@ -9,6 +9,11 @@ LL | (|| Box::new(*(&[0][..])))();
= help: the trait `Sized` is not implemented for `[{integer}]`
note: required by a bound in `Box::<T>::new`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - (|| Box::new(*(&[0][..])))();
LL + (|| Box::new((&[0][..])))();
|
error: aborting due to 1 previous error

View File

@ -0,0 +1,36 @@
#![crate_type = "lib"]
#![deny(improper_ctypes, improper_ctypes_definitions)]
use std::ffi::{CStr, CString};
extern "C" {
fn take_cstr(s: CStr);
//~^ ERROR `extern` block uses type `CStr`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
fn take_cstr_ref(s: &CStr);
//~^ ERROR `extern` block uses type `CStr`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
fn take_cstring(s: CString);
//~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
fn take_cstring_ref(s: &CString);
//~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
fn no_special_help_for_mut_cstring(s: *mut CString);
//~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
//~| HELP consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
fn no_special_help_for_mut_cstring_ref(s: &mut CString);
//~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
//~| HELP consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
}
extern "C" fn rust_take_cstr_ref(s: &CStr) {}
//~^ ERROR `extern` fn uses type `CStr`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
extern "C" fn rust_take_cstring(s: CString) {}
//~^ ERROR `extern` fn uses type `CString`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
extern "C" fn rust_no_special_help_for_mut_cstring(s: *mut CString) {}
extern "C" fn rust_no_special_help_for_mut_cstring_ref(s: &mut CString) {}

View File

@ -0,0 +1,84 @@
error: `extern` block uses type `CStr`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:7:21
|
LL | fn take_cstr(s: CStr);
| ^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
note: the lint level is defined here
--> $DIR/lint-ctypes-cstr.rs:2:9
|
LL | #![deny(improper_ctypes, improper_ctypes_definitions)]
| ^^^^^^^^^^^^^^^
error: `extern` block uses type `CStr`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:10:25
|
LL | fn take_cstr_ref(s: &CStr);
| ^^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
error: `extern` block uses type `CString`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:13:24
|
LL | fn take_cstring(s: CString);
| ^^^^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
error: `extern` block uses type `CString`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:16:28
|
LL | fn take_cstring_ref(s: &CString);
| ^^^^^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
error: `extern` block uses type `CString`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:20:43
|
LL | fn no_special_help_for_mut_cstring(s: *mut CString);
| ^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
error: `extern` block uses type `CString`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:24:47
|
LL | fn no_special_help_for_mut_cstring_ref(s: &mut CString);
| ^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
error: `extern` fn uses type `CStr`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:29:37
|
LL | extern "C" fn rust_take_cstr_ref(s: &CStr) {}
| ^^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
note: the lint level is defined here
--> $DIR/lint-ctypes-cstr.rs:2:26
|
LL | #![deny(improper_ctypes, improper_ctypes_definitions)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `extern` fn uses type `CString`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:32:36
|
LL | extern "C" fn rust_take_cstring(s: CString) {}
| ^^^^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
error: aborting due to 8 previous errors

View File

@ -359,11 +359,6 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
| previous outer attribute
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
help: to annotate the item macro invocation, change the attribute from inner to outer style
|
LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!(); }
|
error: an inner attribute is not permitted following an outer attribute
--> $DIR/attr-stmt-expr-attr-bad.rs:77:32
@ -375,11 +370,6 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
| previous outer attribute
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
help: to annotate the item macro invocation, change the attribute from inner to outer style
|
LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo![]; }
|
error: an inner attribute is not permitted following an outer attribute
--> $DIR/attr-stmt-expr-attr-bad.rs:79:32
@ -391,11 +381,6 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
| previous outer attribute
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
help: to annotate the item macro invocation, change the attribute from inner to outer style
|
LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!{}; }
|
error[E0586]: inclusive range with no end
--> $DIR/attr-stmt-expr-attr-bad.rs:85:35

View File

@ -7,11 +7,6 @@ LL | fn foo() {}
| ----------- the inner attribute doesn't annotate this function
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
help: to annotate the function, change the attribute from inner to outer style
|
LL - #![lang = "foo"]
LL + #[lang = "foo"]
|
error: aborting due to 1 previous error

View File

@ -13,11 +13,6 @@ LL | fn main() {}
| ------------ the inner attribute doesn't annotate this function
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
help: to annotate the function, change the attribute from inner to outer style
|
LL - #![recursion_limit="100"]
LL + #[recursion_limit="100"]
|
error: aborting due to 1 previous error

View File

@ -10,11 +10,6 @@ LL | fn main() {}
| ------------ the inner attribute doesn't annotate this function
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
help: to annotate the function, change the attribute from inner to outer style
|
LL - #![recursion_limit="100"]
LL + #[recursion_limit="100"]
|
error: aborting due to 1 previous error

View File

@ -0,0 +1,10 @@
#![allow(dead_code)]
fn foo() {}
#![feature(iter_array_chunks)] //~ ERROR an inner attribute is not permitted in this context
fn bar() {}
fn main() {
foo();
bar();
}

View File

@ -0,0 +1,12 @@
error: an inner attribute is not permitted in this context
--> $DIR/isgg-invalid-outer-attttr-issue-127930.rs:4:1
|
LL | #![feature(iter_array_chunks)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | fn bar() {}
| ----------- the inner attribute doesn't annotate this function
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
error: aborting due to 1 previous error

View File

@ -6,7 +6,7 @@ fn foo() { }
//~^ ERROR expected outer doc comment
fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function
#[test] //~ ERROR an inner attribute is not permitted in this context
#[cfg(test)] //~ ERROR an inner attribute is not permitted in this context
fn baz() { } //~ NOTE the inner attribute doesn't annotate this function
//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually

View File

@ -6,7 +6,7 @@ fn foo() { }
//~^ ERROR expected outer doc comment
fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function
#![test] //~ ERROR an inner attribute is not permitted in this context
#![cfg(test)] //~ ERROR an inner attribute is not permitted in this context
fn baz() { } //~ NOTE the inner attribute doesn't annotate this function
//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually

View File

@ -15,16 +15,16 @@ LL | /// Misplaced comment...
error: an inner attribute is not permitted in this context
--> $DIR/issue-30318.rs:9:1
|
LL | #![test]
| ^^^^^^^^
LL | #![cfg(test)]
| ^^^^^^^^^^^^^
LL | fn baz() { }
| ------------ the inner attribute doesn't annotate this function
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
help: to annotate the function, change the attribute from inner to outer style
|
LL - #![test]
LL + #[test]
LL - #![cfg(test)]
LL + #[cfg(test)]
|
error[E0753]: expected outer doc comment

View File

@ -7,6 +7,11 @@ LL | let x = *"";
= help: the trait `Sized` is not implemented for `str`
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - let x = *"";
LL + let x = "";
|
error: aborting due to 1 previous error

View File

@ -0,0 +1,30 @@
fn foo() -> impl Sized {
//~^ ERROR the size for values of type `str` cannot be known at compilation time
//~| HELP the trait `Sized` is not implemented for `str`
*"" //~ HELP consider not dereferencing the expression
}
fn bar(_: impl Sized) {}
struct S;
impl S {
fn baz(&self, _: impl Sized) {}
}
fn main() {
let _ = foo();
let x = *"";
//~^ ERROR the size for values of type `str` cannot be known at compilation time
//~| HELP consider not dereferencing the expression
//~| HELP the trait `Sized` is not implemented for `str`
//~| HELP unsized locals are gated as an unstable feature
bar(x);
S.baz(x);
bar(*"");
//~^ ERROR the size for values of type `str` cannot be known at compilation time
//~| HELP consider not dereferencing the expression
//~| HELP the trait `Sized` is not implemented for `str`
S.baz(*"");
//~^ ERROR the size for values of type `str` cannot be known at compilation time
//~| HELP consider not dereferencing the expression
//~| HELP the trait `Sized` is not implemented for `str`
}

View File

@ -0,0 +1,74 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:1:13
|
LL | fn foo() -> impl Sized {
| ^^^^^^^^^^ doesn't have a size known at compile-time
...
LL | *""
| --- return type was inferred to be `str` here
|
= help: the trait `Sized` is not implemented for `str`
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - *""
LL + ""
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:15:9
|
LL | let x = *"";
| ^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - let x = *"";
LL + let x = "";
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:22:9
|
LL | bar(*"");
| --- ^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
= help: the trait `Sized` is not implemented for `str`
note: required by a bound in `bar`
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:6:16
|
LL | fn bar(_: impl Sized) {}
| ^^^^^ required by this bound in `bar`
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - bar(*"");
LL + bar("");
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:26:11
|
LL | S.baz(*"");
| --- ^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
= help: the trait `Sized` is not implemented for `str`
note: required by a bound in `S::baz`
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:10:27
|
LL | fn baz(&self, _: impl Sized) {}
| ^^^^^ required by this bound in `S::baz`
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - S.baz(*"");
LL + S.baz("");
|
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -66,6 +66,11 @@ note: required by a bound in `f_sized`
|
LL | fn f_sized<T: Sized>(t: T) {}
| ^^^^^ required by this bound in `f_sized`
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - f_sized(*ref_cl);
LL + f_sized(ref_cl);
|
error[E0277]: `Rc<{integer}>` cannot be sent between threads safely
--> $DIR/issue-84973-blacklist.rs:27:12

View File

@ -5,21 +5,21 @@
trait Captures<'a> {}
impl<T> Captures<'_> for T {}
type NotCapturedEarly<'a> = impl Sized; //~ [*, o]
type NotCapturedEarly<'a> = impl Sized; //~ ['a: *, 'a: o]
//~^ ERROR: unconstrained opaque type
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [*, o]
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ ['a: *, 'a: o]
//~^ ERROR: unconstrained opaque type
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [*, o, o]
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ ['a: *, 'b: o, 'a: o]
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
//~| ERROR: unconstrained opaque type
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [*, o, o]
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ ['a: *, 'b: o, 'a: o]
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
//~| ERROR: unconstrained opaque type
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [*, *, o, o, o]
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR ['a: *, 'b: *, T: o, 'a: o, 'b: o]
//~^ ERROR: unconstrained opaque type
trait Foo<'i> {
@ -31,24 +31,24 @@ trait Foo<'i> {
}
impl<'i> Foo<'i> for &'i () {
type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
type ImplicitCapture<'a> = impl Sized; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o]
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o]
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type
}
impl<'i> Foo<'i> for () {
type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
type ImplicitCapture<'a> = impl Sized; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o]
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o]
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type
}
@ -59,15 +59,15 @@ impl<'a> Nesting<'a> for &'a () {
type Output = &'a ();
}
type NestedDeeply<'a> =
impl Nesting< //~ [*, o]
impl Nesting< //~ ['a: *, 'a: o]
'a,
Output = impl Nesting< //~ [*, o]
Output = impl Nesting< //~ ['a: *, 'a: o]
'a,
Output = impl Nesting< //~ [*, o]
Output = impl Nesting< //~ ['a: *, 'a: o]
'a,
Output = impl Nesting< //~ [*, o]
Output = impl Nesting< //~ ['a: *, 'a: o]
'a,
Output = impl Nesting<'a> //~ [*, o]
Output = impl Nesting<'a> //~ ['a: *, 'a: o]
>
>,
>,

View File

@ -110,73 +110,73 @@ LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
|
= note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:8:29
|
LL | type NotCapturedEarly<'a> = impl Sized;
| ^^^^^^^^^^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:11:26
|
LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, o, o]
error: ['a: *, 'b: o, 'a: o]
--> $DIR/variance.rs:14:56
|
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
| ^^^^^^^^^^
error: [*, o, o]
error: ['a: *, 'b: o, 'a: o]
--> $DIR/variance.rs:18:49
|
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o, o]
error: ['a: *, 'b: *, T: o, 'a: o, 'b: o]
--> $DIR/variance.rs:22:27
|
LL | type Bar<'a, 'b: 'b, T> = impl Sized;
| ^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:34:32
|
LL | type ImplicitCapture<'a> = impl Sized;
| ^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:37:42
|
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:40:39
|
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:45:32
|
LL | type ImplicitCapture<'a> = impl Sized;
| ^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:48:42
|
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:51:39
|
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:62:5
|
LL | / impl Nesting<
@ -188,7 +188,7 @@ LL | | >,
LL | | >;
| |_____^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:64:18
|
LL | Output = impl Nesting<
@ -201,7 +201,7 @@ LL | | >,
LL | | >,
| |_________^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:66:22
|
LL | Output = impl Nesting<
@ -214,7 +214,7 @@ LL | | >
LL | | >,
| |_____________^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:68:26
|
LL | Output = impl Nesting<
@ -224,7 +224,7 @@ LL | | Output = impl Nesting<'a>
LL | | >
| |_________________^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:70:30
|
LL | Output = impl Nesting<'a>

View File

@ -123,6 +123,11 @@ help: consider removing the `?Sized` bound to make the type parameter `Sized`
LL - fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
LL + fn f3<X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - let y = *x2;
LL + let y = x2;
|
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized6.rs:26:10
@ -177,6 +182,11 @@ help: consider removing the `?Sized` bound to make the type parameter `Sized`
LL - fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
LL + fn f4<X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - let y = *x2;
LL + let y = x2;
|
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized6.rs:34:10

View File

@ -10,7 +10,7 @@ trait Trait {
}
#[rustc_variance]
struct Foo<T: Trait> { //~ ERROR [o]
struct Foo<T: Trait> { //~ ERROR [T: o]
field: [u8; <T as Trait>::Const]
//~^ ERROR: unconstrained generic constant
}

View File

@ -9,7 +9,7 @@ help: try adding a `where` bound
LL | struct Foo<T: Trait> where [(); <T as Trait>::Const]: {
| ++++++++++++++++++++++++++++++++
error: [o]
error: [T: o]
--> $DIR/variance-associated-consts.rs:13:1
|
LL | struct Foo<T: Trait> {

View File

@ -10,12 +10,12 @@ trait Trait<'a> {
}
#[rustc_variance]
struct Foo<'a, T : Trait<'a>> { //~ ERROR [+, +]
struct Foo<'a, T : Trait<'a>> { //~ ERROR ['a: +, T: +]
field: (T, &'a ())
}
#[rustc_variance]
struct Bar<'a, T : Trait<'a>> { //~ ERROR [o, o]
struct Bar<'a, T : Trait<'a>> { //~ ERROR ['a: o, T: o]
field: <T as Trait<'a>>::Type
}

View File

@ -1,10 +1,10 @@
error: [+, +]
error: ['a: +, T: +]
--> $DIR/variance-associated-types.rs:13:1
|
LL | struct Foo<'a, T : Trait<'a>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o]
error: ['a: o, T: o]
--> $DIR/variance-associated-types.rs:18:1
|
LL | struct Bar<'a, T : Trait<'a>> {

View File

@ -4,7 +4,7 @@
// For better or worse, associated types are invariant, and hence we
// get an invariant result for `'a`.
#[rustc_variance]
struct Foo<'a> { //~ ERROR [o]
struct Foo<'a> { //~ ERROR ['a: o]
x: Box<dyn Fn(i32) -> &'a i32 + 'static>
}

View File

@ -1,4 +1,4 @@
error: [o]
error: ['a: o]
--> $DIR/variance-object-types.rs:7:1
|
LL | struct Foo<'a> {

View File

@ -6,7 +6,7 @@
// Regions that just appear in normal spots are contravariant:
#[rustc_variance]
struct Test2<'a, 'b, 'c> { //~ ERROR [+, +, +]
struct Test2<'a, 'b, 'c> { //~ ERROR ['a: +, 'b: +, 'c: +]
x: &'a isize,
y: &'b [isize],
c: &'c str
@ -15,7 +15,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR [+, +, +]
// Those same annotations in function arguments become covariant:
#[rustc_variance]
struct Test3<'a, 'b, 'c> { //~ ERROR [-, -, -]
struct Test3<'a, 'b, 'c> { //~ ERROR ['a: -, 'b: -, 'c: -]
x: extern "Rust" fn(&'a isize),
y: extern "Rust" fn(&'b [isize]),
c: extern "Rust" fn(&'c str),
@ -24,7 +24,7 @@ struct Test3<'a, 'b, 'c> { //~ ERROR [-, -, -]
// Mutability induces invariance:
#[rustc_variance]
struct Test4<'a, 'b:'a> { //~ ERROR [+, o]
struct Test4<'a, 'b:'a> { //~ ERROR ['a: +, 'b: o]
x: &'a mut &'b isize,
}
@ -32,7 +32,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR [+, o]
// contravariant context:
#[rustc_variance]
struct Test5<'a, 'b:'a> { //~ ERROR [-, o]
struct Test5<'a, 'b:'a> { //~ ERROR ['a: -, 'b: o]
x: extern "Rust" fn(&'a mut &'b isize),
}
@ -42,14 +42,14 @@ struct Test5<'a, 'b:'a> { //~ ERROR [-, o]
// argument list occurs in an invariant context.
#[rustc_variance]
struct Test6<'a, 'b:'a> { //~ ERROR [+, o]
struct Test6<'a, 'b:'a> { //~ ERROR ['a: +, 'b: o]
x: &'a mut extern "Rust" fn(&'b isize),
}
// No uses at all is bivariant:
#[rustc_variance]
struct Test7<'a> { //~ ERROR [*]
struct Test7<'a> { //~ ERROR ['a: *]
//~^ ERROR: `'a` is never used
x: isize
}
@ -57,7 +57,7 @@ struct Test7<'a> { //~ ERROR [*]
// Try enums too.
#[rustc_variance]
enum Test8<'a, 'b, 'c:'b> { //~ ERROR [-, +, o]
enum Test8<'a, 'b, 'c:'b> { //~ ERROR ['a: -, 'b: +, 'c: o]
Test8A(extern "Rust" fn(&'a isize)),
Test8B(&'b [isize]),
Test8C(&'b mut &'c str),

View File

@ -6,43 +6,43 @@ LL | struct Test7<'a> {
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
error: [+, +, +]
error: ['a: +, 'b: +, 'c: +]
--> $DIR/variance-regions-direct.rs:9:1
|
LL | struct Test2<'a, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: [-, -, -]
error: ['a: -, 'b: -, 'c: -]
--> $DIR/variance-regions-direct.rs:18:1
|
LL | struct Test3<'a, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: [+, o]
error: ['a: +, 'b: o]
--> $DIR/variance-regions-direct.rs:27:1
|
LL | struct Test4<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: [-, o]
error: ['a: -, 'b: o]
--> $DIR/variance-regions-direct.rs:35:1
|
LL | struct Test5<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: [+, o]
error: ['a: +, 'b: o]
--> $DIR/variance-regions-direct.rs:45:1
|
LL | struct Test6<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: [*]
error: ['a: *]
--> $DIR/variance-regions-direct.rs:52:1
|
LL | struct Test7<'a> {
| ^^^^^^^^^^^^^^^^
error: [-, +, o]
error: ['a: -, 'b: +, 'c: o]
--> $DIR/variance-regions-direct.rs:60:1
|
LL | enum Test8<'a, 'b, 'c:'b> {

View File

@ -5,7 +5,7 @@
#![feature(rustc_attrs)]
#[rustc_variance]
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *]
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR ['a: -, 'b: +, 'c: o, 'd: *]
//~^ ERROR: `'d` is never used
Test8A(extern "Rust" fn(&'a isize)),
Test8B(&'b [isize]),
@ -13,25 +13,25 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *]
}
#[rustc_variance]
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, +, -]
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR ['w: *, 'x: o, 'y: +, 'z: -]
//~^ ERROR: `'w` is never used
f: Base<'z, 'y, 'x, 'w>
}
#[rustc_variance] // Combine - and + to yield o
struct Derived2<'a, 'b:'a, 'c> { //~ ERROR [o, o, *]
struct Derived2<'a, 'b:'a, 'c> { //~ ERROR ['a: o, 'b: o, 'c: *]
//~^ ERROR: `'c` is never used
f: Base<'a, 'a, 'b, 'c>
}
#[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
struct Derived3<'a:'b, 'b, 'c> { //~ ERROR [o, +, *]
struct Derived3<'a:'b, 'b, 'c> { //~ ERROR ['a: o, 'b: +, 'c: *]
//~^ ERROR: `'c` is never used
f: Base<'a, 'b, 'a, 'c>
}
#[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here)
struct Derived4<'a, 'b, 'c:'b> { //~ ERROR [-, +, o]
struct Derived4<'a, 'b, 'c:'b> { //~ ERROR ['a: -, 'b: +, 'c: o]
f: Base<'a, 'b, 'c, 'a>
}

View File

@ -30,31 +30,31 @@ LL | struct Derived3<'a:'b, 'b, 'c> {
|
= help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData`
error: [-, +, o, *]
error: ['a: -, 'b: +, 'c: o, 'd: *]
--> $DIR/variance-regions-indirect.rs:8:1
|
LL | enum Base<'a, 'b, 'c:'b, 'd> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, o, +, -]
error: ['w: *, 'x: o, 'y: +, 'z: -]
--> $DIR/variance-regions-indirect.rs:16:1
|
LL | struct Derived1<'w, 'x:'y, 'y, 'z> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o, *]
error: ['a: o, 'b: o, 'c: *]
--> $DIR/variance-regions-indirect.rs:22:1
|
LL | struct Derived2<'a, 'b:'a, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, +, *]
error: ['a: o, 'b: +, 'c: *]
--> $DIR/variance-regions-indirect.rs:28:1
|
LL | struct Derived3<'a:'b, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [-, +, o]
error: ['a: -, 'b: +, 'c: o]
--> $DIR/variance-regions-indirect.rs:34:1
|
LL | struct Derived4<'a, 'b, 'c:'b> {

View File

@ -13,24 +13,24 @@ trait Setter<T> {
}
#[rustc_variance]
struct TestStruct<U,T:Setter<U>> { //~ ERROR [+, +]
struct TestStruct<U,T:Setter<U>> { //~ ERROR [U: +, T: +]
t: T, u: U
}
#[rustc_variance]
enum TestEnum<U,T:Setter<U>> { //~ ERROR [*, +]
enum TestEnum<U,T:Setter<U>> { //~ ERROR [U: *, T: +]
//~^ ERROR: `U` is never used
Foo(T)
}
#[rustc_variance]
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [*, +]
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [U: *, T: +]
//~^ ERROR: `U` is never used
t: T
}
#[rustc_variance]
struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR [*, +]
struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR [U: *, T: +]
//~^ ERROR: `U` is never used
t: T
}

View File

@ -25,25 +25,25 @@ LL | struct TestBox<U,T:Getter<U>+Setter<U>> {
= help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead
error: [+, +]
error: [U: +, T: +]
--> $DIR/variance-trait-bounds.rs:16:1
|
LL | struct TestStruct<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, +]
error: [U: *, T: +]
--> $DIR/variance-trait-bounds.rs:21:1
|
LL | enum TestEnum<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, +]
error: [U: *, T: +]
--> $DIR/variance-trait-bounds.rs:27:1
|
LL | struct TestContraStruct<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, +]
error: [U: *, T: +]
--> $DIR/variance-trait-bounds.rs:33:1
|
LL | struct TestBox<U,T:Getter<U>+Setter<U>> {

View File

@ -11,7 +11,7 @@ use std::mem;
trait T { fn foo(&self); }
#[rustc_variance]
struct TOption<'a> { //~ ERROR [+]
struct TOption<'a> { //~ ERROR ['a: +]
v: Option<Box<dyn T + 'a>>,
}

View File

@ -1,4 +1,4 @@
error: [+]
error: ['a: +]
--> $DIR/variance-trait-object-bound.rs:14:1
|
LL | struct TOption<'a> {

View File

@ -4,24 +4,24 @@
#![feature(rustc_attrs)]
#[rustc_variance]
struct TestImm<A, B> { //~ ERROR [+, +]
struct TestImm<A, B> { //~ ERROR [A: +, B: +]
x: A,
y: B,
}
#[rustc_variance]
struct TestMut<A, B:'static> { //~ ERROR [+, o]
struct TestMut<A, B:'static> { //~ ERROR [A: +, B: o]
x: A,
y: &'static mut B,
}
#[rustc_variance]
struct TestIndirect<A:'static, B:'static> { //~ ERROR [+, o]
struct TestIndirect<A:'static, B:'static> { //~ ERROR [A: +, B: o]
m: TestMut<A, B>
}
#[rustc_variance]
struct TestIndirect2<A:'static, B:'static> { //~ ERROR [o, o]
struct TestIndirect2<A:'static, B:'static> { //~ ERROR [A: o, B: o]
n: TestMut<A, B>,
m: TestMut<B, A>
}
@ -35,7 +35,7 @@ trait Setter<A> {
}
#[rustc_variance]
struct TestObject<A, R> { //~ ERROR [o, o]
struct TestObject<A, R> { //~ ERROR [A: o, R: o]
n: Box<dyn Setter<A>+Send>,
m: Box<dyn Getter<R>+Send>,
}

View File

@ -1,28 +1,28 @@
error: [+, +]
error: [A: +, B: +]
--> $DIR/variance-types-bounds.rs:7:1
|
LL | struct TestImm<A, B> {
| ^^^^^^^^^^^^^^^^^^^^
error: [+, o]
error: [A: +, B: o]
--> $DIR/variance-types-bounds.rs:13:1
|
LL | struct TestMut<A, B:'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [+, o]
error: [A: +, B: o]
--> $DIR/variance-types-bounds.rs:19:1
|
LL | struct TestIndirect<A:'static, B:'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o]
error: [A: o, B: o]
--> $DIR/variance-types-bounds.rs:24:1
|
LL | struct TestIndirect2<A:'static, B:'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o]
error: [A: o, R: o]
--> $DIR/variance-types-bounds.rs:38:1
|
LL | struct TestObject<A, R> {

View File

@ -7,32 +7,32 @@ use std::cell::Cell;
// not considered bivariant.
#[rustc_variance]
struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR [+, o, o]
struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR ['a: +, A: o, B: o]
t: &'a mut (A,B)
}
#[rustc_variance]
struct InvariantCell<A> { //~ ERROR [o]
struct InvariantCell<A> { //~ ERROR [A: o]
t: Cell<A>
}
#[rustc_variance]
struct InvariantIndirect<A> { //~ ERROR [o]
struct InvariantIndirect<A> { //~ ERROR [A: o]
t: InvariantCell<A>
}
#[rustc_variance]
struct Covariant<A> { //~ ERROR [+]
struct Covariant<A> { //~ ERROR [A: +]
t: A, u: fn() -> A
}
#[rustc_variance]
struct Contravariant<A> { //~ ERROR [-]
struct Contravariant<A> { //~ ERROR [A: -]
t: fn(A)
}
#[rustc_variance]
enum Enum<A,B,C> { //~ ERROR [+, -, o]
enum Enum<A,B,C> { //~ ERROR [A: +, B: -, C: o]
Foo(Covariant<A>),
Bar(Contravariant<B>),
Zed(Covariant<C>,Contravariant<C>)

View File

@ -1,34 +1,34 @@
error: [+, o, o]
error: ['a: +, A: o, B: o]
--> $DIR/variance-types.rs:10:1
|
LL | struct InvariantMut<'a,A:'a,B:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o]
error: [A: o]
--> $DIR/variance-types.rs:15:1
|
LL | struct InvariantCell<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: [o]
error: [A: o]
--> $DIR/variance-types.rs:20:1
|
LL | struct InvariantIndirect<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [+]
error: [A: +]
--> $DIR/variance-types.rs:25:1
|
LL | struct Covariant<A> {
| ^^^^^^^^^^^^^^^^^^^
error: [-]
error: [A: -]
--> $DIR/variance-types.rs:30:1
|
LL | struct Contravariant<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: [+, -, o]
error: [A: +, B: -, C: o]
--> $DIR/variance-types.rs:35:1
|
LL | enum Enum<A,B,C> {

View File

@ -951,6 +951,7 @@ libs = [
"@joboet",
"@jhpratt",
"@tgross35",
"@thomcc",
]
bootstrap = [
"@Mark-Simulacrum",