mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-17 06:26:55 +00:00
Auto merge of #139622 - matthiaskrgr:rollup-8ri1vid, r=matthiaskrgr
Rollup of 13 pull requests Successful merges: - #138167 (Small code improvement in rustdoc hidden stripper) - #138605 (Clean up librustdoc::html::render to be better encapsulated) - #139423 (Suppress missing field error when autoderef bottoms out in infer) - #139449 (match ergonomics: replace `peel_off_references` with a recursive call) - #139507 (compiletest: Trim whitespace from environment variable names) - #139530 (Remove some dead or leftover code related to rustc-intrinsic abi removal) - #139560 (fix title of offset_of_enum feature) - #139563 (emit a better error message for using the macro incorrectly) - #139568 (Don't use empty trait names) - #139580 (Temporarily leave the review rotation) - #139589 (saethlin is back from vacation) - #139592 (rustdoc: Enable Markdown extensions when looking for doctests) - #139599 (Tracking issue template: fine-grained information on style update status) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
69b3959afe
5
.github/ISSUE_TEMPLATE/tracking_issue.md
vendored
5
.github/ISSUE_TEMPLATE/tracking_issue.md
vendored
@ -41,7 +41,10 @@ for larger features an implementation could be broken up into multiple PRs.
|
||||
- [ ] Implement the RFC (cc @rust-lang/XXX -- can anyone write up mentoring
|
||||
instructions?)
|
||||
- [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide])
|
||||
- [ ] Formatting for new syntax has been added to the [Style Guide] ([nightly-style-procedure])
|
||||
- [ ] Style updates for any new syntax ([nightly-style-procedure])
|
||||
- [ ] Style team decision on new formatting
|
||||
- [ ] Formatting for new syntax has been added to the [Style Guide]
|
||||
- [ ] (non-blocking) Formatting has been implemented in `rustfmt`
|
||||
- [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide])
|
||||
|
||||
[stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr
|
||||
|
@ -234,7 +234,7 @@ mod llvm_enzyme {
|
||||
let meta_item_vec: ThinVec<MetaItemInner> = match meta_item.kind {
|
||||
ast::MetaItemKind::List(ref vec) => vec.clone(),
|
||||
_ => {
|
||||
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
|
||||
dcx.emit_err(errors::AutoDiffMissingConfig { span: item.span() });
|
||||
return vec![item];
|
||||
}
|
||||
};
|
||||
|
@ -1,8 +1,10 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
An intrinsic was declared without being a function.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0622
|
||||
```no_run
|
||||
#![feature(intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
|
@ -397,7 +397,7 @@ E0618: 0618,
|
||||
E0619: 0619,
|
||||
E0620: 0620,
|
||||
E0621: 0621,
|
||||
E0622: 0622,
|
||||
E0622: 0622, // REMOVED: rustc-intrinsic ABI was removed
|
||||
E0623: 0623,
|
||||
E0624: 0624,
|
||||
E0625: 0625,
|
||||
|
@ -719,7 +719,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
def_id,
|
||||
tcx.def_ident_span(def_id).unwrap(),
|
||||
i.name,
|
||||
ExternAbi::Rust,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -787,16 +786,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
for item in items {
|
||||
let def_id = item.id.owner_id.def_id;
|
||||
|
||||
if tcx.has_attr(def_id, sym::rustc_intrinsic) {
|
||||
intrinsic::check_intrinsic_type(
|
||||
tcx,
|
||||
item.id.owner_id.def_id,
|
||||
item.span,
|
||||
item.ident.name,
|
||||
abi,
|
||||
);
|
||||
}
|
||||
|
||||
let generics = tcx.generics_of(def_id);
|
||||
let own_counts = generics.own_counts();
|
||||
if generics.own_params.len() - own_counts.lifetimes != 0 {
|
||||
|
@ -1,9 +1,8 @@
|
||||
//! Type-checking for the `#[rustc_intrinsic]` intrinsics that the compiler exposes.
|
||||
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{DiagMessage, struct_span_code_err};
|
||||
use rustc_hir::{self as hir, Safety};
|
||||
use rustc_errors::DiagMessage;
|
||||
use rustc_hir::{self as hir};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
@ -26,17 +25,10 @@ fn equate_intrinsic_type<'tcx>(
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
) {
|
||||
let (generics, span) = match tcx.hir_node_by_def_id(def_id) {
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { generics, .. }, .. })
|
||||
| hir::Node::ForeignItem(hir::ForeignItem {
|
||||
kind: hir::ForeignItemKind::Fn(_, _, generics),
|
||||
..
|
||||
}) => (tcx.generics_of(def_id), generics.span),
|
||||
_ => {
|
||||
struct_span_code_err!(tcx.dcx(), span, E0622, "intrinsic must be a function")
|
||||
.with_span_label(span, "expected a function")
|
||||
.emit();
|
||||
return;
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { generics, .. }, .. }) => {
|
||||
(tcx.generics_of(def_id), generics.span)
|
||||
}
|
||||
_ => tcx.dcx().span_bug(span, "intrinsic must be a function"),
|
||||
};
|
||||
let own_counts = generics.own_counts();
|
||||
|
||||
@ -70,13 +62,7 @@ fn equate_intrinsic_type<'tcx>(
|
||||
}
|
||||
|
||||
/// Returns the unsafety of the given intrinsic.
|
||||
pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Safety {
|
||||
let has_safe_attr = if tcx.has_attr(intrinsic_id, sym::rustc_intrinsic) {
|
||||
tcx.fn_sig(intrinsic_id).skip_binder().safety()
|
||||
} else {
|
||||
// Old-style intrinsics are never safe
|
||||
Safety::Unsafe
|
||||
};
|
||||
fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Safety {
|
||||
let is_in_list = match tcx.item_name(intrinsic_id.into()) {
|
||||
// When adding a new intrinsic to this list,
|
||||
// it's usually worth updating that intrinsic's documentation
|
||||
@ -148,7 +134,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
|
||||
_ => hir::Safety::Unsafe,
|
||||
};
|
||||
|
||||
if has_safe_attr != is_in_list {
|
||||
if tcx.fn_sig(intrinsic_id).skip_binder().safety() != is_in_list {
|
||||
tcx.dcx().struct_span_err(
|
||||
tcx.def_span(intrinsic_id),
|
||||
DiagMessage::from(format!(
|
||||
@ -163,12 +149,11 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
|
||||
|
||||
/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
|
||||
/// and in `library/core/src/intrinsics.rs`.
|
||||
pub fn check_intrinsic_type(
|
||||
pub(crate) fn check_intrinsic_type(
|
||||
tcx: TyCtxt<'_>,
|
||||
intrinsic_id: LocalDefId,
|
||||
span: Span,
|
||||
intrinsic_name: Symbol,
|
||||
abi: ExternAbi,
|
||||
) {
|
||||
let generics = tcx.generics_of(intrinsic_id);
|
||||
let param = |n| {
|
||||
@ -706,7 +691,7 @@ pub fn check_intrinsic_type(
|
||||
};
|
||||
(n_tps, 0, n_cts, inputs, output, safety)
|
||||
};
|
||||
let sig = tcx.mk_fn_sig(inputs, output, false, safety, abi);
|
||||
let sig = tcx.mk_fn_sig(inputs, output, false, safety, ExternAbi::Rust);
|
||||
let sig = ty::Binder::bind_with_vars(sig, bound_vars);
|
||||
equate_intrinsic_type(tcx, span, intrinsic_id, n_tps, n_lts, n_cts, sig)
|
||||
}
|
||||
|
@ -2920,8 +2920,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
// We failed to check the expression, report an error.
|
||||
|
||||
// Emits an error if we deref an infer variable, like calling `.field` on a base type of &_.
|
||||
self.structurally_resolve_type(autoderef.span(), autoderef.final_ty(false));
|
||||
// Emits an error if we deref an infer variable, like calling `.field` on a base type
|
||||
// of `&_`. We can also use this to suppress unnecessary "missing field" errors that
|
||||
// will follow ambiguity errors.
|
||||
let final_ty = self.structurally_resolve_type(autoderef.span(), autoderef.final_ty(false));
|
||||
if let ty::Error(_) = final_ty.kind() {
|
||||
return final_ty;
|
||||
}
|
||||
|
||||
if let Some((adjustments, did)) = private_candidate {
|
||||
// (#90483) apply adjustments to avoid ExprUseVisitor from
|
||||
|
@ -163,9 +163,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
enum AdjustMode {
|
||||
/// Peel off all immediate reference types.
|
||||
Peel,
|
||||
/// Reset binding mode to the initial mode.
|
||||
/// Used for destructuring assignment, where we don't want any match ergonomics.
|
||||
Reset,
|
||||
/// Pass on the input binding mode and expected type.
|
||||
Pass,
|
||||
}
|
||||
@ -321,77 +318,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// Conversely, inside this module, `check_pat_top` should never be used.
|
||||
#[instrument(level = "debug", skip(self, pat_info))]
|
||||
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx>) {
|
||||
let PatInfo { binding_mode, max_ref_mutbl, top_info: ti, current_depth, .. } = pat_info;
|
||||
|
||||
let path_res = match pat.kind {
|
||||
let opt_path_res = match pat.kind {
|
||||
PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
|
||||
Some(self.resolve_ty_and_res_fully_qualified_call(qpath, *hir_id, *span))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
|
||||
let (expected, binding_mode, max_ref_mutbl) =
|
||||
self.calc_default_binding_mode(pat, expected, binding_mode, adjust_mode, max_ref_mutbl);
|
||||
let pat_info = PatInfo {
|
||||
binding_mode,
|
||||
max_ref_mutbl,
|
||||
top_info: ti,
|
||||
decl_origin: pat_info.decl_origin,
|
||||
current_depth: current_depth + 1,
|
||||
};
|
||||
|
||||
let ty = match pat.kind {
|
||||
PatKind::Missing | PatKind::Wild | PatKind::Err(_) => expected,
|
||||
// We allow any type here; we ensure that the type is uninhabited during match checking.
|
||||
PatKind::Never => expected,
|
||||
PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
|
||||
let ty = self.check_pat_path(
|
||||
*hir_id,
|
||||
pat.hir_id,
|
||||
*span,
|
||||
qpath,
|
||||
path_res.unwrap(),
|
||||
expected,
|
||||
&pat_info.top_info,
|
||||
);
|
||||
self.write_ty(*hir_id, ty);
|
||||
ty
|
||||
}
|
||||
PatKind::Expr(lt) => self.check_pat_lit(pat.span, lt, expected, &pat_info.top_info),
|
||||
PatKind::Range(lhs, rhs, _) => {
|
||||
self.check_pat_range(pat.span, lhs, rhs, expected, &pat_info.top_info)
|
||||
}
|
||||
PatKind::Binding(ba, var_id, ident, sub) => {
|
||||
self.check_pat_ident(pat, ba, var_id, ident, sub, expected, pat_info)
|
||||
}
|
||||
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
|
||||
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
|
||||
}
|
||||
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
|
||||
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
|
||||
}
|
||||
PatKind::Guard(pat, cond) => {
|
||||
self.check_pat(pat, expected, pat_info);
|
||||
self.check_expr_has_type_or_error(cond, self.tcx.types.bool, |_| {});
|
||||
expected
|
||||
}
|
||||
PatKind::Or(pats) => {
|
||||
for pat in pats {
|
||||
self.check_pat(pat, expected, pat_info);
|
||||
}
|
||||
expected
|
||||
}
|
||||
PatKind::Tuple(elements, ddpos) => {
|
||||
self.check_pat_tuple(pat.span, elements, ddpos, expected, pat_info)
|
||||
}
|
||||
PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info),
|
||||
PatKind::Deref(inner) => self.check_pat_deref(pat.span, inner, expected, pat_info),
|
||||
PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info),
|
||||
PatKind::Slice(before, slice, after) => {
|
||||
self.check_pat_slice(pat.span, before, slice, after, expected, pat_info)
|
||||
}
|
||||
};
|
||||
|
||||
let adjust_mode = self.calc_adjust_mode(pat, opt_path_res.map(|(res, ..)| res));
|
||||
let ty = self.check_pat_inner(pat, opt_path_res, adjust_mode, expected, pat_info);
|
||||
self.write_ty(pat.hir_id, ty);
|
||||
|
||||
// (note_1): In most of the cases where (note_1) is referenced
|
||||
@ -437,27 +371,126 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
|
||||
}
|
||||
|
||||
/// Compute the new expected type and default binding mode from the old ones
|
||||
/// as well as the pattern form we are currently checking.
|
||||
fn calc_default_binding_mode(
|
||||
// Helper to avoid resolving the same path pattern several times.
|
||||
fn check_pat_inner(
|
||||
&self,
|
||||
pat: &'tcx Pat<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
def_br: ByRef,
|
||||
opt_path_res: Option<(Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>])>,
|
||||
adjust_mode: AdjustMode,
|
||||
max_ref_mutbl: MutblCap,
|
||||
) -> (Ty<'tcx>, ByRef, MutblCap) {
|
||||
expected: Ty<'tcx>,
|
||||
pat_info: PatInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
#[cfg(debug_assertions)]
|
||||
if def_br == ByRef::Yes(Mutability::Mut)
|
||||
&& max_ref_mutbl != MutblCap::Mut
|
||||
if pat_info.binding_mode == ByRef::Yes(Mutability::Mut)
|
||||
&& pat_info.max_ref_mutbl != MutblCap::Mut
|
||||
&& self.downgrade_mut_inside_shared()
|
||||
{
|
||||
span_bug!(pat.span, "Pattern mutability cap violated!");
|
||||
}
|
||||
match adjust_mode {
|
||||
AdjustMode::Pass => (expected, def_br, max_ref_mutbl),
|
||||
AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut),
|
||||
AdjustMode::Peel => self.peel_off_references(pat, expected, def_br, max_ref_mutbl),
|
||||
|
||||
// Resolve type if needed.
|
||||
let expected = if let AdjustMode::Peel = adjust_mode
|
||||
&& pat.default_binding_modes
|
||||
{
|
||||
self.try_structurally_resolve_type(pat.span, expected)
|
||||
} else {
|
||||
expected
|
||||
};
|
||||
let old_pat_info = pat_info;
|
||||
let pat_info = PatInfo { current_depth: old_pat_info.current_depth + 1, ..old_pat_info };
|
||||
|
||||
match pat.kind {
|
||||
// Peel off a `&` or `&mut` from the scrutinee type. See the examples in
|
||||
// `tests/ui/rfcs/rfc-2005-default-binding-mode`.
|
||||
_ if let AdjustMode::Peel = adjust_mode
|
||||
&& pat.default_binding_modes
|
||||
&& let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() =>
|
||||
{
|
||||
debug!("inspecting {:?}", expected);
|
||||
|
||||
debug!("current discriminant is Ref, inserting implicit deref");
|
||||
// Preserve the reference type. We'll need it later during THIR lowering.
|
||||
self.typeck_results
|
||||
.borrow_mut()
|
||||
.pat_adjustments_mut()
|
||||
.entry(pat.hir_id)
|
||||
.or_default()
|
||||
.push(expected);
|
||||
|
||||
let mut binding_mode = ByRef::Yes(match pat_info.binding_mode {
|
||||
// If default binding mode is by value, make it `ref` or `ref mut`
|
||||
// (depending on whether we observe `&` or `&mut`).
|
||||
ByRef::No |
|
||||
// When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`).
|
||||
ByRef::Yes(Mutability::Mut) => inner_mutability,
|
||||
// Once a `ref`, always a `ref`.
|
||||
// This is because a `& &mut` cannot mutate the underlying value.
|
||||
ByRef::Yes(Mutability::Not) => Mutability::Not,
|
||||
});
|
||||
|
||||
let mut max_ref_mutbl = pat_info.max_ref_mutbl;
|
||||
if self.downgrade_mut_inside_shared() {
|
||||
binding_mode = binding_mode.cap_ref_mutability(max_ref_mutbl.as_mutbl());
|
||||
}
|
||||
if binding_mode == ByRef::Yes(Mutability::Not) {
|
||||
max_ref_mutbl = MutblCap::Not;
|
||||
}
|
||||
debug!("default binding mode is now {:?}", binding_mode);
|
||||
|
||||
// Use the old pat info to keep `current_depth` to its old value.
|
||||
let new_pat_info = PatInfo { binding_mode, max_ref_mutbl, ..old_pat_info };
|
||||
// Recurse with the new expected type.
|
||||
self.check_pat_inner(pat, opt_path_res, adjust_mode, inner_ty, new_pat_info)
|
||||
}
|
||||
PatKind::Missing | PatKind::Wild | PatKind::Err(_) => expected,
|
||||
// We allow any type here; we ensure that the type is uninhabited during match checking.
|
||||
PatKind::Never => expected,
|
||||
PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
|
||||
let ty = self.check_pat_path(
|
||||
*hir_id,
|
||||
pat.hir_id,
|
||||
*span,
|
||||
qpath,
|
||||
opt_path_res.unwrap(),
|
||||
expected,
|
||||
&pat_info.top_info,
|
||||
);
|
||||
self.write_ty(*hir_id, ty);
|
||||
ty
|
||||
}
|
||||
PatKind::Expr(lt) => self.check_pat_lit(pat.span, lt, expected, &pat_info.top_info),
|
||||
PatKind::Range(lhs, rhs, _) => {
|
||||
self.check_pat_range(pat.span, lhs, rhs, expected, &pat_info.top_info)
|
||||
}
|
||||
PatKind::Binding(ba, var_id, ident, sub) => {
|
||||
self.check_pat_ident(pat, ba, var_id, ident, sub, expected, pat_info)
|
||||
}
|
||||
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
|
||||
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
|
||||
}
|
||||
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
|
||||
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
|
||||
}
|
||||
PatKind::Guard(pat, cond) => {
|
||||
self.check_pat(pat, expected, pat_info);
|
||||
self.check_expr_has_type_or_error(cond, self.tcx.types.bool, |_| {});
|
||||
expected
|
||||
}
|
||||
PatKind::Or(pats) => {
|
||||
for pat in pats {
|
||||
self.check_pat(pat, expected, pat_info);
|
||||
}
|
||||
expected
|
||||
}
|
||||
PatKind::Tuple(elements, ddpos) => {
|
||||
self.check_pat_tuple(pat.span, elements, ddpos, expected, pat_info)
|
||||
}
|
||||
PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info),
|
||||
PatKind::Deref(inner) => self.check_pat_deref(pat.span, inner, expected, pat_info),
|
||||
PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info),
|
||||
PatKind::Slice(before, slice, after) => {
|
||||
self.check_pat_slice(pat.span, before, slice, after, expected, pat_info)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -465,11 +498,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
///
|
||||
/// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`.
|
||||
fn calc_adjust_mode(&self, pat: &'tcx Pat<'tcx>, opt_path_res: Option<Res>) -> AdjustMode {
|
||||
// When we perform destructuring assignment, we disable default match bindings, which are
|
||||
// unintuitive in this context.
|
||||
if !pat.default_binding_modes {
|
||||
return AdjustMode::Reset;
|
||||
}
|
||||
match &pat.kind {
|
||||
// Type checking these product-like types successfully always require
|
||||
// that the expected type be of those types and not reference types.
|
||||
@ -526,64 +554,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Peel off as many immediately nested `& mut?` from the expected type as possible
|
||||
/// and return the new expected type and binding default binding mode.
|
||||
/// The adjustments vector, if non-empty is stored in a table.
|
||||
fn peel_off_references(
|
||||
&self,
|
||||
pat: &'tcx Pat<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
mut def_br: ByRef,
|
||||
mut max_ref_mutbl: MutblCap,
|
||||
) -> (Ty<'tcx>, ByRef, MutblCap) {
|
||||
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
|
||||
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
||||
// for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
|
||||
// the `Some(5)` which is not of type Ref.
|
||||
//
|
||||
// For each ampersand peeled off, update the binding mode and push the original
|
||||
// type into the adjustments vector.
|
||||
//
|
||||
// See the examples in `ui/match-defbm*.rs`.
|
||||
let mut pat_adjustments = vec![];
|
||||
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() {
|
||||
debug!("inspecting {:?}", expected);
|
||||
|
||||
debug!("current discriminant is Ref, inserting implicit deref");
|
||||
// Preserve the reference type. We'll need it later during THIR lowering.
|
||||
pat_adjustments.push(expected);
|
||||
|
||||
expected = self.try_structurally_resolve_type(pat.span, inner_ty);
|
||||
def_br = ByRef::Yes(match def_br {
|
||||
// If default binding mode is by value, make it `ref` or `ref mut`
|
||||
// (depending on whether we observe `&` or `&mut`).
|
||||
ByRef::No |
|
||||
// When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`).
|
||||
ByRef::Yes(Mutability::Mut) => inner_mutability,
|
||||
// Once a `ref`, always a `ref`.
|
||||
// This is because a `& &mut` cannot mutate the underlying value.
|
||||
ByRef::Yes(Mutability::Not) => Mutability::Not,
|
||||
});
|
||||
}
|
||||
|
||||
if self.downgrade_mut_inside_shared() {
|
||||
def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
|
||||
}
|
||||
if def_br == ByRef::Yes(Mutability::Not) {
|
||||
max_ref_mutbl = MutblCap::Not;
|
||||
}
|
||||
|
||||
if !pat_adjustments.is_empty() {
|
||||
debug!("default binding mode is now {:?}", def_br);
|
||||
self.typeck_results
|
||||
.borrow_mut()
|
||||
.pat_adjustments_mut()
|
||||
.insert(pat.hir_id, pat_adjustments);
|
||||
}
|
||||
|
||||
(expected, def_br, max_ref_mutbl)
|
||||
}
|
||||
|
||||
fn check_pat_expr_unadjusted(&self, lt: &'tcx hir::PatExpr<'tcx>) -> Ty<'tcx> {
|
||||
let ty = match <.kind {
|
||||
rustc_hir::PatExprKind::Lit { lit, negated } => {
|
||||
|
@ -602,21 +602,13 @@ impl<'a> Parser<'a> {
|
||||
let polarity = self.parse_polarity();
|
||||
|
||||
// Parse both types and traits as a type, then reinterpret if necessary.
|
||||
let err_path = |span| ast::Path::from_ident(Ident::new(kw::Empty, span));
|
||||
let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
|
||||
{
|
||||
let span = self.prev_token.span.between(self.token.span);
|
||||
self.dcx().emit_err(errors::MissingTraitInTraitImpl {
|
||||
return Err(self.dcx().create_err(errors::MissingTraitInTraitImpl {
|
||||
span,
|
||||
for_span: span.to(self.token.span),
|
||||
});
|
||||
|
||||
P(Ty {
|
||||
kind: TyKind::Path(None, err_path(span)),
|
||||
span,
|
||||
id: DUMMY_NODE_ID,
|
||||
tokens: None,
|
||||
})
|
||||
}));
|
||||
} else {
|
||||
self.parse_ty_with_generics_recovery(&generics)?
|
||||
};
|
||||
@ -657,6 +649,7 @@ impl<'a> Parser<'a> {
|
||||
other => {
|
||||
if let TyKind::ImplTrait(_, bounds) = other
|
||||
&& let [bound] = bounds.as_slice()
|
||||
&& let GenericBound::Trait(poly_trait_ref) = bound
|
||||
{
|
||||
// Suggest removing extra `impl` keyword:
|
||||
// `impl<T: Default> impl Default for Wrapper<T>`
|
||||
@ -666,12 +659,12 @@ impl<'a> Parser<'a> {
|
||||
extra_impl_kw,
|
||||
impl_trait_span: ty_first.span,
|
||||
});
|
||||
poly_trait_ref.trait_ref.path.clone()
|
||||
} else {
|
||||
self.dcx().emit_err(errors::ExpectedTraitInTraitImplFoundType {
|
||||
span: ty_first.span,
|
||||
});
|
||||
return Err(self.dcx().create_err(
|
||||
errors::ExpectedTraitInTraitImplFoundType { span: ty_first.span },
|
||||
));
|
||||
}
|
||||
err_path(ty_first.span)
|
||||
}
|
||||
};
|
||||
let trait_ref = TraitRef { path, ref_id: ty_first.id };
|
||||
|
@ -296,9 +296,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
) -> Option<LexicalScopeBinding<'ra>> {
|
||||
assert!(ns == TypeNS || ns == ValueNS);
|
||||
let orig_ident = ident;
|
||||
if ident.name == kw::Empty {
|
||||
return Some(LexicalScopeBinding::Res(Res::Err));
|
||||
}
|
||||
let (general_span, normalized_span) = if ident.name == kw::SelfUpper {
|
||||
// FIXME(jseyfried) improve `Self` hygiene
|
||||
let empty_span = ident.span.with_ctxt(SyntaxContext::root());
|
||||
|
@ -1,4 +1,4 @@
|
||||
# `offset_of_slice`
|
||||
# `offset_of_enum`
|
||||
|
||||
The tracking issue for this feature is: [#120141]
|
||||
|
||||
|
@ -721,7 +721,7 @@ pub(crate) fn find_codes<T: doctest::DocTestVisitor>(
|
||||
extra_info: Option<&ExtraInfo<'_>>,
|
||||
include_non_rust: bool,
|
||||
) {
|
||||
let mut parser = Parser::new(doc).into_offset_iter();
|
||||
let mut parser = Parser::new_ext(doc, main_body_opts()).into_offset_iter();
|
||||
let mut prev_offset = 0;
|
||||
let mut nb_lines = 0;
|
||||
let mut register_header = None;
|
||||
|
@ -13,6 +13,9 @@
|
||||
//! is cloned per-thread and contains information about what is currently being
|
||||
//! rendered.
|
||||
//!
|
||||
//! The main entry point to the rendering system is the implementation of
|
||||
//! `FormatRenderer` on `Context`.
|
||||
//!
|
||||
//! In order to speed up rendering (mostly because of markdown rendering), the
|
||||
//! rendering process has been parallelized. This parallelization is only
|
||||
//! exposed through the `crate` method on the context, and then also from the
|
||||
@ -90,7 +93,7 @@ pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display {
|
||||
/// Specifies whether rendering directly implemented trait items or ones from a certain Deref
|
||||
/// impl.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub(crate) enum AssocItemRender<'a> {
|
||||
enum AssocItemRender<'a> {
|
||||
All,
|
||||
DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
|
||||
}
|
||||
@ -98,7 +101,7 @@ pub(crate) enum AssocItemRender<'a> {
|
||||
/// For different handling of associated items from the Deref target of a type rather than the type
|
||||
/// itself.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub(crate) enum RenderMode {
|
||||
enum RenderMode {
|
||||
Normal,
|
||||
ForDeref { mut_: bool },
|
||||
}
|
||||
@ -126,7 +129,7 @@ pub(crate) struct IndexItem {
|
||||
|
||||
/// A type used for the search index.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub(crate) struct RenderType {
|
||||
struct RenderType {
|
||||
id: Option<RenderTypeId>,
|
||||
generics: Option<Vec<RenderType>>,
|
||||
bindings: Option<Vec<(RenderTypeId, Vec<RenderType>)>>,
|
||||
@ -137,7 +140,7 @@ impl RenderType {
|
||||
// The contents of the lists are always integers in self-terminating hex
|
||||
// form, handled by `RenderTypeId::write_to_string`, so no commas are
|
||||
// needed to separate the items.
|
||||
pub fn write_to_string(&self, string: &mut String) {
|
||||
fn write_to_string(&self, string: &mut String) {
|
||||
fn write_optional_id(id: Option<RenderTypeId>, string: &mut String) {
|
||||
// 0 is a sentinel, everything else is one-indexed
|
||||
match id {
|
||||
@ -177,7 +180,7 @@ impl RenderType {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum RenderTypeId {
|
||||
enum RenderTypeId {
|
||||
DefId(DefId),
|
||||
Primitive(clean::PrimitiveType),
|
||||
AssociatedType(Symbol),
|
||||
@ -186,7 +189,7 @@ pub(crate) enum RenderTypeId {
|
||||
}
|
||||
|
||||
impl RenderTypeId {
|
||||
pub fn write_to_string(&self, string: &mut String) {
|
||||
fn write_to_string(&self, string: &mut String) {
|
||||
let id: i32 = match &self {
|
||||
// 0 is a sentinel, everything else is one-indexed
|
||||
// concrete type
|
||||
@ -209,7 +212,7 @@ pub(crate) struct IndexItemFunctionType {
|
||||
}
|
||||
|
||||
impl IndexItemFunctionType {
|
||||
pub fn write_to_string<'a>(
|
||||
fn write_to_string<'a>(
|
||||
&'a self,
|
||||
string: &mut String,
|
||||
backref_queue: &mut VecDeque<&'a IndexItemFunctionType>,
|
||||
@ -309,7 +312,7 @@ impl ItemEntry {
|
||||
}
|
||||
|
||||
impl ItemEntry {
|
||||
pub(crate) fn print(&self) -> impl fmt::Display {
|
||||
fn print(&self) -> impl fmt::Display {
|
||||
fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name)))
|
||||
}
|
||||
}
|
||||
@ -760,7 +763,7 @@ fn short_item_info(
|
||||
|
||||
// Render the list of items inside one of the sections "Trait Implementations",
|
||||
// "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
|
||||
pub(crate) fn render_impls(
|
||||
fn render_impls(
|
||||
cx: &Context<'_>,
|
||||
mut w: impl Write,
|
||||
impls: &[&Impl],
|
||||
@ -1201,7 +1204,7 @@ impl<'a> AssocItemLink<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_section_heading(
|
||||
fn write_section_heading(
|
||||
title: &str,
|
||||
id: &str,
|
||||
extra_class: Option<&str>,
|
||||
@ -1226,7 +1229,7 @@ fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display {
|
||||
write_section_heading(title, id, None, "")
|
||||
}
|
||||
|
||||
pub(crate) fn render_all_impls(
|
||||
fn render_all_impls(
|
||||
mut w: impl Write,
|
||||
cx: &Context<'_>,
|
||||
containing_item: &clean::Item,
|
||||
@ -1473,10 +1476,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn notable_traits_button(
|
||||
ty: &clean::Type,
|
||||
cx: &Context<'_>,
|
||||
) -> Option<impl fmt::Display> {
|
||||
fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Option<impl fmt::Display> {
|
||||
if ty.is_unit() {
|
||||
// Very common fast path.
|
||||
return None;
|
||||
@ -1588,10 +1588,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
|
||||
(format!("{:#}", ty.print(cx)), out)
|
||||
}
|
||||
|
||||
pub(crate) fn notable_traits_json<'a>(
|
||||
tys: impl Iterator<Item = &'a clean::Type>,
|
||||
cx: &Context<'_>,
|
||||
) -> String {
|
||||
fn notable_traits_json<'a>(tys: impl Iterator<Item = &'a clean::Type>, cx: &Context<'_>) -> String {
|
||||
let mut mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect();
|
||||
mp.sort_by(|(name1, _html1), (name2, _html2)| name1.cmp(name2));
|
||||
struct NotableTraitsMap(Vec<(String, String)>);
|
||||
@ -2171,7 +2168,7 @@ fn render_rightside(
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn render_impl_summary(
|
||||
fn render_impl_summary(
|
||||
cx: &Context<'_>,
|
||||
i: &Impl,
|
||||
parent: &clean::Item,
|
||||
|
@ -91,19 +91,21 @@ impl DocFolder for Stripper<'_, '_> {
|
||||
|
||||
if let clean::ImportItem(clean::Import { source, .. }) = &i.kind
|
||||
&& let Some(source_did) = source.did
|
||||
&& let Some(import_def_id) = i.def_id().and_then(|def_id| def_id.as_local())
|
||||
{
|
||||
let reexports = reexport_chain(self.tcx, import_def_id, source_did);
|
||||
|
||||
// Check if any reexport in the chain has a hidden source
|
||||
let has_hidden_source = reexports
|
||||
.iter()
|
||||
.filter_map(|reexport| reexport.id())
|
||||
.any(|reexport_did| self.tcx.is_doc_hidden(reexport_did))
|
||||
|| self.tcx.is_doc_hidden(source_did);
|
||||
|
||||
if has_hidden_source {
|
||||
if self.tcx.is_doc_hidden(source_did) {
|
||||
return None;
|
||||
} else if let Some(import_def_id) = i.def_id().and_then(|def_id| def_id.as_local()) {
|
||||
let reexports = reexport_chain(self.tcx, import_def_id, source_did);
|
||||
|
||||
// Check if any reexport in the chain has a hidden source
|
||||
let has_hidden_source = reexports
|
||||
.iter()
|
||||
.filter_map(|reexport| reexport.id())
|
||||
.any(|reexport_did| self.tcx.is_doc_hidden(reexport_did));
|
||||
|
||||
if has_hidden_source {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,7 +452,7 @@ impl TestProps {
|
||||
ln,
|
||||
UNSET_EXEC_ENV,
|
||||
&mut self.unset_exec_env,
|
||||
|r| r,
|
||||
|r| r.trim().to_owned(),
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
@ -464,7 +464,7 @@ impl TestProps {
|
||||
ln,
|
||||
UNSET_RUSTC_ENV,
|
||||
&mut self.unset_rustc_env,
|
||||
|r| r,
|
||||
|r| r.trim().to_owned(),
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
@ -997,16 +997,13 @@ impl Config {
|
||||
|
||||
fn parse_env(nv: String) -> (String, String) {
|
||||
// nv is either FOO or FOO=BAR
|
||||
let mut strs: Vec<String> = nv.splitn(2, '=').map(str::to_owned).collect();
|
||||
|
||||
match strs.len() {
|
||||
1 => (strs.pop().unwrap(), String::new()),
|
||||
2 => {
|
||||
let end = strs.pop().unwrap();
|
||||
(strs.pop().unwrap(), end)
|
||||
}
|
||||
n => panic!("Expected 1 or 2 strings, not {}", n),
|
||||
}
|
||||
// FIXME(Zalathar): The form without `=` seems to be unused; should
|
||||
// we drop support for it?
|
||||
let (name, value) = nv.split_once('=').unwrap_or((&nv, ""));
|
||||
// Trim whitespace from the name, so that `//@ exec-env: FOO=BAR`
|
||||
// sees the name as `FOO` and not ` FOO`.
|
||||
let name = name.trim();
|
||||
(name.to_owned(), value.to_owned())
|
||||
}
|
||||
|
||||
fn parse_pp_exact(&self, line: &str, testfile: &Path) -> Option<PathBuf> {
|
||||
|
@ -968,16 +968,16 @@ impl<'test> TestCx<'test> {
|
||||
delete_after_success: bool,
|
||||
) -> ProcRes {
|
||||
let prepare_env = |cmd: &mut Command| {
|
||||
for key in &self.props.unset_exec_env {
|
||||
cmd.env_remove(key);
|
||||
}
|
||||
|
||||
for (key, val) in &self.props.exec_env {
|
||||
cmd.env(key, val);
|
||||
}
|
||||
for (key, val) in env_extra {
|
||||
cmd.env(key, val);
|
||||
}
|
||||
|
||||
for key in &self.props.unset_exec_env {
|
||||
cmd.env_remove(key);
|
||||
}
|
||||
};
|
||||
|
||||
let proc_res = match &*self.config.target {
|
||||
|
18
tests/rustdoc-ui/multi-par-footnote.rs
Normal file
18
tests/rustdoc-ui/multi-par-footnote.rs
Normal file
@ -0,0 +1,18 @@
|
||||
//@ check-pass
|
||||
//@ compile-flags:--test
|
||||
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
|
||||
// Regression test for #139064.
|
||||
|
||||
/// Example
|
||||
///
|
||||
/// Footnote with multiple paragraphs[^multiple]
|
||||
///
|
||||
/// [^multiple]:
|
||||
/// One
|
||||
///
|
||||
/// Two
|
||||
///
|
||||
/// Three
|
||||
pub fn add(left: u64, right: u64) -> u64 {
|
||||
left + right
|
||||
}
|
5
tests/rustdoc-ui/multi-par-footnote.stdout
Normal file
5
tests/rustdoc-ui/multi-par-footnote.stdout
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
|
||||
|
@ -63,7 +63,7 @@ fn dummy() {
|
||||
// Malformed, where args?
|
||||
#[autodiff]
|
||||
pub fn f7(x: f64) {
|
||||
//~^ ERROR autodiff must be applied to function
|
||||
//~^ ERROR autodiff requires at least a name and mode
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ pub fn f8(x: f64) {
|
||||
// Invalid attribute syntax
|
||||
#[autodiff = ""]
|
||||
pub fn f9(x: f64) {
|
||||
//~^ ERROR autodiff must be applied to function
|
||||
//~^ ERROR autodiff requires at least a name and mode
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ error: autodiff must be applied to function
|
||||
LL | let add_one_v2 = |x: u32| -> u32 { x + 1 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: autodiff must be applied to function
|
||||
error: autodiff requires at least a name and mode
|
||||
--> $DIR/autodiff_illegal.rs:65:1
|
||||
|
|
||||
LL | / pub fn f7(x: f64) {
|
||||
@ -80,7 +80,7 @@ LL | | unimplemented!()
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: autodiff must be applied to function
|
||||
error: autodiff requires at least a name and mode
|
||||
--> $DIR/autodiff_illegal.rs:79:1
|
||||
|
|
||||
LL | / pub fn f9(x: f64) {
|
||||
|
23
tests/ui/compiletest-self-test/trim-env-name.rs
Normal file
23
tests/ui/compiletest-self-test/trim-env-name.rs
Normal file
@ -0,0 +1,23 @@
|
||||
//@ edition: 2024
|
||||
//@ revisions: set unset
|
||||
//@ run-pass
|
||||
//@ ignore-cross-compile (assume that non-cross targets have working env vars)
|
||||
//@ rustc-env: MY_RUSTC_ENV = my-rustc-value
|
||||
//@ exec-env: MY_EXEC_ENV = my-exec-value
|
||||
//@[unset] unset-rustc-env: MY_RUSTC_ENV
|
||||
//@[unset] unset-exec-env: MY_EXEC_ENV
|
||||
|
||||
// Check that compiletest trims whitespace from environment variable names
|
||||
// specified in `rustc-env` and `exec-env` directives, so that
|
||||
// `//@ exec-env: FOO=bar` sees the name as `FOO` and not ` FOO`.
|
||||
//
|
||||
// Values are currently not trimmed.
|
||||
//
|
||||
// Since this is a compiletest self-test, only run it on non-cross targets,
|
||||
// to avoid having to worry about weird targets that don't support env vars.
|
||||
|
||||
fn main() {
|
||||
let is_set = cfg!(set);
|
||||
assert_eq!(option_env!("MY_RUSTC_ENV"), is_set.then_some(" my-rustc-value"));
|
||||
assert_eq!(std::env::var("MY_EXEC_ENV").ok().as_deref(), is_set.then_some(" my-exec-value"));
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#![feature(intrinsics)]
|
||||
|
||||
extern "C" {
|
||||
|
||||
#[rustc_intrinsic]
|
||||
pub static atomic_singlethreadfence_seqcst: unsafe extern "C" fn();
|
||||
//~^ ERROR intrinsic must be a function [E0622]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
atomic_singlethreadfence_seqcst();
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
error[E0622]: intrinsic must be a function
|
||||
--> $DIR/E0622.rs:6:5
|
||||
|
|
||||
LL | pub static atomic_singlethreadfence_seqcst: unsafe extern "C" fn();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a function
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0622`.
|
4
tests/ui/parser/impl-parsing-2.rs
Normal file
4
tests/ui/parser/impl-parsing-2.rs
Normal file
@ -0,0 +1,4 @@
|
||||
impl ! {} // OK
|
||||
|
||||
default unsafe FAIL //~ ERROR expected item, found keyword `unsafe`
|
||||
//~^ ERROR `default` is not followed by an item
|
18
tests/ui/parser/impl-parsing-2.stderr
Normal file
18
tests/ui/parser/impl-parsing-2.stderr
Normal file
@ -0,0 +1,18 @@
|
||||
error: `default` is not followed by an item
|
||||
--> $DIR/impl-parsing-2.rs:3:1
|
||||
|
|
||||
LL | default unsafe FAIL
|
||||
| ^^^^^^^ the `default` qualifier
|
||||
|
|
||||
= note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
|
||||
|
||||
error: expected item, found keyword `unsafe`
|
||||
--> $DIR/impl-parsing-2.rs:3:9
|
||||
|
|
||||
LL | default unsafe FAIL
|
||||
| ^^^^^^ expected item
|
||||
|
|
||||
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -2,9 +2,4 @@ impl ! {} // OK
|
||||
impl ! where u8: Copy {} // OK
|
||||
|
||||
impl Trait Type {} //~ ERROR missing `for` in a trait impl
|
||||
impl Trait .. {} //~ ERROR missing `for` in a trait impl
|
||||
impl ?Sized for Type {} //~ ERROR expected a trait, found type
|
||||
impl ?Sized for .. {} //~ ERROR expected a trait, found type
|
||||
|
||||
default unsafe FAIL //~ ERROR expected item, found keyword `unsafe`
|
||||
//~^ ERROR `default` is not followed by an item
|
||||
|
@ -9,44 +9,11 @@ help: add `for` here
|
||||
LL | impl Trait for Type {}
|
||||
| +++
|
||||
|
||||
error: missing `for` in a trait impl
|
||||
--> $DIR/impl-parsing.rs:5:11
|
||||
|
|
||||
LL | impl Trait .. {}
|
||||
| ^
|
||||
|
|
||||
help: add `for` here
|
||||
|
|
||||
LL | impl Trait for .. {}
|
||||
| +++
|
||||
|
||||
error: expected a trait, found type
|
||||
--> $DIR/impl-parsing.rs:6:6
|
||||
--> $DIR/impl-parsing.rs:5:6
|
||||
|
|
||||
LL | impl ?Sized for Type {}
|
||||
| ^^^^^^
|
||||
|
||||
error: expected a trait, found type
|
||||
--> $DIR/impl-parsing.rs:7:6
|
||||
|
|
||||
LL | impl ?Sized for .. {}
|
||||
| ^^^^^^
|
||||
|
||||
error: `default` is not followed by an item
|
||||
--> $DIR/impl-parsing.rs:9:1
|
||||
|
|
||||
LL | default unsafe FAIL
|
||||
| ^^^^^^^ the `default` qualifier
|
||||
|
|
||||
= note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
|
||||
|
||||
error: expected item, found keyword `unsafe`
|
||||
--> $DIR/impl-parsing.rs:9:9
|
||||
|
|
||||
LL | default unsafe FAIL
|
||||
| ^^^^^^ expected item
|
||||
|
|
||||
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -58,6 +58,5 @@ fn main() {
|
||||
let mut buffer = ArrayVec::new();
|
||||
let x = buffer.last().unwrap().0.clone();
|
||||
//~^ ERROR type annotations needed
|
||||
//~| ERROR no field `0` on type `&_`
|
||||
buffer.reverse();
|
||||
}
|
||||
|
@ -4,13 +4,6 @@ error[E0282]: type annotations needed
|
||||
LL | let x = buffer.last().unwrap().0.clone();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
|
||||
|
||||
error[E0609]: no field `0` on type `&_`
|
||||
--> $DIR/issue-65611.rs:59:36
|
||||
|
|
||||
LL | let x = buffer.last().unwrap().0.clone();
|
||||
| ^ unknown field
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0609.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
||||
For more information about this error, try `rustc --explain E0282`.
|
||||
|
@ -1123,8 +1123,8 @@ cc = ["@ZuseZ4"]
|
||||
warn_non_default_branch.enable = true
|
||||
contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
|
||||
users_on_vacation = [
|
||||
"fmease",
|
||||
"jyn514",
|
||||
"saethlin",
|
||||
"Noratrieb",
|
||||
]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user