Auto merge of #107435 - matthiaskrgr:rollup-if5h6yu, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #106618 (Disable `linux_ext` in wasm32 and fortanix rustdoc builds.) - #107097 (Fix def-use dominance check) - #107154 (library/std/sys_common: Define MIN_ALIGN for m68k-unknown-linux-gnu) - #107397 (Gracefully exit if --keep-stage flag is used on a clean source tree) - #107401 (remove the usize field from CandidateSource::AliasBound) - #107413 (make more pleasant to read) - #107422 (Also erase substs for new infcx in pin move error) - #107425 (Check for missing space between fat arrow and range pattern) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
a29efccb1e
19 changed files with 221 additions and 44 deletions
|
@ -1128,8 +1128,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
"{place_name} {partially_str}moved due to this method call{loop_message}",
|
"{place_name} {partially_str}moved due to this method call{loop_message}",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
|
// Erase and shadow everything that could be passed to the new infcx.
|
||||||
let ty = tcx.erase_regions(moved_place.ty(self.body, tcx).ty);
|
let ty = tcx.erase_regions(moved_place.ty(self.body, tcx).ty);
|
||||||
|
let method_substs = tcx.erase_regions(method_substs);
|
||||||
|
|
||||||
if let ty::Adt(def, substs) = ty.kind()
|
if let ty::Adt(def, substs) = ty.kind()
|
||||||
&& Some(def.did()) == tcx.lang_items().pin_type()
|
&& Some(def.did()) == tcx.lang_items().pin_type()
|
||||||
&& let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind()
|
&& let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind()
|
||||||
|
|
|
@ -191,7 +191,7 @@ pub unsafe fn create_module<'ll>(
|
||||||
//
|
//
|
||||||
// FIXME(#34960)
|
// FIXME(#34960)
|
||||||
let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or("");
|
let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or("");
|
||||||
let custom_llvm_used = cfg_llvm_root.trim() != "";
|
let custom_llvm_used = !cfg_llvm_root.trim().is_empty();
|
||||||
|
|
||||||
if !custom_llvm_used && target_data_layout != llvm_data_layout {
|
if !custom_llvm_used && target_data_layout != llvm_data_layout {
|
||||||
bug!(
|
bug!(
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
|
|
||||||
// Arguments get assigned to by means of the function being called
|
// Arguments get assigned to by means of the function being called
|
||||||
for arg in mir.args_iter() {
|
for arg in mir.args_iter() {
|
||||||
analyzer.assign(arg, mir::START_BLOCK.start_location());
|
analyzer.assign(arg, DefLocation::Argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there exists a local definition that dominates all uses of that local,
|
// If there exists a local definition that dominates all uses of that local,
|
||||||
|
@ -64,7 +64,22 @@ enum LocalKind {
|
||||||
/// A scalar or a scalar pair local that is neither defined nor used.
|
/// A scalar or a scalar pair local that is neither defined nor used.
|
||||||
Unused,
|
Unused,
|
||||||
/// A scalar or a scalar pair local with a single definition that dominates all uses.
|
/// A scalar or a scalar pair local with a single definition that dominates all uses.
|
||||||
SSA(mir::Location),
|
SSA(DefLocation),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
|
enum DefLocation {
|
||||||
|
Argument,
|
||||||
|
Body(Location),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DefLocation {
|
||||||
|
fn dominates(self, location: Location, dominators: &Dominators<mir::BasicBlock>) -> bool {
|
||||||
|
match self {
|
||||||
|
DefLocation::Argument => true,
|
||||||
|
DefLocation::Body(def) => def.successor_within_block().dominates(location, dominators),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
|
struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
|
||||||
|
@ -74,17 +89,13 @@ struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
|
impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
|
||||||
fn assign(&mut self, local: mir::Local, location: Location) {
|
fn assign(&mut self, local: mir::Local, location: DefLocation) {
|
||||||
let kind = &mut self.locals[local];
|
let kind = &mut self.locals[local];
|
||||||
match *kind {
|
match *kind {
|
||||||
LocalKind::ZST => {}
|
LocalKind::ZST => {}
|
||||||
LocalKind::Memory => {}
|
LocalKind::Memory => {}
|
||||||
LocalKind::Unused => {
|
LocalKind::Unused => *kind = LocalKind::SSA(location),
|
||||||
*kind = LocalKind::SSA(location);
|
LocalKind::SSA(_) => *kind = LocalKind::Memory,
|
||||||
}
|
|
||||||
LocalKind::SSA(_) => {
|
|
||||||
*kind = LocalKind::Memory;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +177,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
|
||||||
debug!("visit_assign(place={:?}, rvalue={:?})", place, rvalue);
|
debug!("visit_assign(place={:?}, rvalue={:?})", place, rvalue);
|
||||||
|
|
||||||
if let Some(local) = place.as_local() {
|
if let Some(local) = place.as_local() {
|
||||||
self.assign(local, location);
|
self.assign(local, DefLocation::Body(location));
|
||||||
if self.locals[local] != LocalKind::Memory {
|
if self.locals[local] != LocalKind::Memory {
|
||||||
let decl_span = self.fx.mir.local_decls[local].source_info.span;
|
let decl_span = self.fx.mir.local_decls[local].source_info.span;
|
||||||
if !self.fx.rvalue_creates_operand(rvalue, decl_span) {
|
if !self.fx.rvalue_creates_operand(rvalue, decl_span) {
|
||||||
|
@ -189,7 +200,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
|
||||||
match context {
|
match context {
|
||||||
PlaceContext::MutatingUse(MutatingUseContext::Call)
|
PlaceContext::MutatingUse(MutatingUseContext::Call)
|
||||||
| PlaceContext::MutatingUse(MutatingUseContext::Yield) => {
|
| PlaceContext::MutatingUse(MutatingUseContext::Yield) => {
|
||||||
self.assign(local, location);
|
self.assign(local, DefLocation::Body(location));
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaceContext::NonUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {}
|
PlaceContext::NonUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {}
|
||||||
|
|
|
@ -199,6 +199,17 @@ parse_match_arm_body_without_braces = `match` arm body without braces
|
||||||
} with a body
|
} with a body
|
||||||
.suggestion_use_comma_not_semicolon = use a comma to end a `match` arm expression
|
.suggestion_use_comma_not_semicolon = use a comma to end a `match` arm expression
|
||||||
|
|
||||||
|
parse_inclusive_range_extra_equals = unexpected `=` after inclusive range
|
||||||
|
.suggestion_remove_eq = use `..=` instead
|
||||||
|
.note = inclusive ranges end with a single equals sign (`..=`)
|
||||||
|
|
||||||
|
parse_inclusive_range_match_arrow = unexpected `=>` after open range
|
||||||
|
.suggestion_add_space = add a space between the pattern and `=>`
|
||||||
|
|
||||||
|
parse_inclusive_range_no_end = inclusive range with no end
|
||||||
|
.suggestion_open_range = use `..` instead
|
||||||
|
.note = inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||||
|
|
||||||
parse_struct_literal_not_allowed_here = struct literals are not allowed here
|
parse_struct_literal_not_allowed_here = struct literals are not allowed here
|
||||||
.suggestion = surround the struct literal with parentheses
|
.suggestion = surround the struct literal with parentheses
|
||||||
|
|
||||||
|
|
|
@ -649,6 +649,48 @@ pub(crate) struct MatchArmBodyWithoutBraces {
|
||||||
pub sub: MatchArmBodyWithoutBracesSugg,
|
pub sub: MatchArmBodyWithoutBracesSugg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parse_inclusive_range_extra_equals)]
|
||||||
|
#[note]
|
||||||
|
pub(crate) struct InclusiveRangeExtraEquals {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion(
|
||||||
|
suggestion_remove_eq,
|
||||||
|
style = "short",
|
||||||
|
code = "..=",
|
||||||
|
applicability = "maybe-incorrect"
|
||||||
|
)]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parse_inclusive_range_match_arrow)]
|
||||||
|
pub(crate) struct InclusiveRangeMatchArrow {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
#[suggestion(
|
||||||
|
suggestion_add_space,
|
||||||
|
style = "verbose",
|
||||||
|
code = " ",
|
||||||
|
applicability = "machine-applicable"
|
||||||
|
)]
|
||||||
|
pub after_pat: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parse_inclusive_range_no_end, code = "E0586")]
|
||||||
|
#[note]
|
||||||
|
pub(crate) struct InclusiveRangeNoEnd {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion(
|
||||||
|
suggestion_open_range,
|
||||||
|
code = "..",
|
||||||
|
applicability = "machine-applicable",
|
||||||
|
style = "short"
|
||||||
|
)]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
pub(crate) enum MatchArmBodyWithoutBracesSugg {
|
pub(crate) enum MatchArmBodyWithoutBracesSugg {
|
||||||
#[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")]
|
#[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")]
|
||||||
|
|
|
@ -3168,7 +3168,7 @@ impl<'a> Parser<'a> {
|
||||||
limits: RangeLimits,
|
limits: RangeLimits,
|
||||||
) -> ExprKind {
|
) -> ExprKind {
|
||||||
if end.is_none() && limits == RangeLimits::Closed {
|
if end.is_none() && limits == RangeLimits::Closed {
|
||||||
self.inclusive_range_with_incorrect_end(self.prev_token.span);
|
self.inclusive_range_with_incorrect_end();
|
||||||
ExprKind::Err
|
ExprKind::Err
|
||||||
} else {
|
} else {
|
||||||
ExprKind::Range(start, end, limits)
|
ExprKind::Range(start, end, limits)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use super::{ForceCollect, Parser, PathStyle, TrailingToken};
|
use super::{ForceCollect, Parser, PathStyle, TrailingToken};
|
||||||
use crate::errors::RemoveLet;
|
use crate::errors::{
|
||||||
|
InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, RemoveLet,
|
||||||
|
};
|
||||||
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
||||||
use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
|
use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
|
@ -9,7 +11,7 @@ use rustc_ast::{
|
||||||
PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
|
PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
|
||||||
};
|
};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
|
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
|
||||||
use rustc_session::errors::ExprParenthesesNeeded;
|
use rustc_session::errors::ExprParenthesesNeeded;
|
||||||
use rustc_span::source_map::{respan, Span, Spanned};
|
use rustc_span::source_map::{respan, Span, Spanned};
|
||||||
use rustc_span::symbol::{kw, sym, Ident};
|
use rustc_span::symbol::{kw, sym, Ident};
|
||||||
|
@ -746,21 +748,24 @@ impl<'a> Parser<'a> {
|
||||||
// Parsing e.g. `X..`.
|
// Parsing e.g. `X..`.
|
||||||
if let RangeEnd::Included(_) = re.node {
|
if let RangeEnd::Included(_) = re.node {
|
||||||
// FIXME(Centril): Consider semantic errors instead in `ast_validation`.
|
// FIXME(Centril): Consider semantic errors instead in `ast_validation`.
|
||||||
self.inclusive_range_with_incorrect_end(re.span);
|
self.inclusive_range_with_incorrect_end();
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
Ok(PatKind::Range(Some(begin), end, re))
|
Ok(PatKind::Range(Some(begin), end, re))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn inclusive_range_with_incorrect_end(&mut self, span: Span) {
|
pub(super) fn inclusive_range_with_incorrect_end(&mut self) {
|
||||||
let tok = &self.token;
|
let tok = &self.token;
|
||||||
|
let span = self.prev_token.span;
|
||||||
// If the user typed "..==" instead of "..=", we want to give them
|
// If the user typed "..==" instead of "..=", we want to give them
|
||||||
// a specific error message telling them to use "..=".
|
// a specific error message telling them to use "..=".
|
||||||
|
// If they typed "..=>", suggest they use ".. =>".
|
||||||
// Otherwise, we assume that they meant to type a half open exclusive
|
// Otherwise, we assume that they meant to type a half open exclusive
|
||||||
// range and give them an error telling them to do that instead.
|
// range and give them an error telling them to do that instead.
|
||||||
if matches!(tok.kind, token::Eq) && tok.span.lo() == span.hi() {
|
let no_space = tok.span.lo() == span.hi();
|
||||||
|
match tok.kind {
|
||||||
|
token::Eq if no_space => {
|
||||||
let span_with_eq = span.to(tok.span);
|
let span_with_eq = span.to(tok.span);
|
||||||
|
|
||||||
// Ensure the user doesn't receive unhelpful unexpected token errors
|
// Ensure the user doesn't receive unhelpful unexpected token errors
|
||||||
|
@ -770,23 +775,25 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.error_inclusive_range_with_extra_equals(span_with_eq);
|
self.error_inclusive_range_with_extra_equals(span_with_eq);
|
||||||
} else {
|
}
|
||||||
self.error_inclusive_range_with_no_end(span);
|
token::Gt if no_space => {
|
||||||
|
self.error_inclusive_range_match_arrow(span);
|
||||||
|
}
|
||||||
|
_ => self.error_inclusive_range_with_no_end(span),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_inclusive_range_with_extra_equals(&self, span: Span) {
|
fn error_inclusive_range_with_extra_equals(&self, span: Span) {
|
||||||
self.struct_span_err(span, "unexpected `=` after inclusive range")
|
self.sess.emit_err(InclusiveRangeExtraEquals { span });
|
||||||
.span_suggestion_short(span, "use `..=` instead", "..=", Applicability::MaybeIncorrect)
|
}
|
||||||
.note("inclusive ranges end with a single equals sign (`..=`)")
|
|
||||||
.emit();
|
fn error_inclusive_range_match_arrow(&self, span: Span) {
|
||||||
|
let after_pat = span.with_hi(span.hi() - rustc_span::BytePos(1)).shrink_to_hi();
|
||||||
|
self.sess.emit_err(InclusiveRangeMatchArrow { span, after_pat });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_inclusive_range_with_no_end(&self, span: Span) {
|
fn error_inclusive_range_with_no_end(&self, span: Span) {
|
||||||
struct_span_err!(self.sess.span_diagnostic, span, E0586, "inclusive range with no end")
|
self.sess.emit_err(InclusiveRangeNoEnd { span });
|
||||||
.span_suggestion_short(span, "use `..` instead", "..", Applicability::MachineApplicable)
|
|
||||||
.note("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)")
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a range-to pattern, `..X` or `..=X` where `X` remains to be parsed.
|
/// Parse a range-to pattern, `..X` or `..=X` where `X` remains to be parsed.
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub(super) enum CandidateSource {
|
||||||
/// let _y = x.clone();
|
/// let _y = x.clone();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
AliasBound(usize),
|
AliasBound,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq {
|
pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq {
|
||||||
|
@ -242,8 +242,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
// NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate.
|
// NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate.
|
||||||
// This doesn't work as long as we use `CandidateSource` in winnowing.
|
// This doesn't work as long as we use `CandidateSource` in winnowing.
|
||||||
let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty));
|
let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty));
|
||||||
// FIXME: This is broken if we care about the `usize` of `AliasBound` because the self type
|
|
||||||
// could be normalized to yet another projection with different item bounds.
|
|
||||||
let normalized_candidates = self.assemble_and_evaluate_candidates(goal);
|
let normalized_candidates = self.assemble_and_evaluate_candidates(goal);
|
||||||
for mut normalized_candidate in normalized_candidates {
|
for mut normalized_candidate in normalized_candidates {
|
||||||
normalized_candidate.result =
|
normalized_candidate.result =
|
||||||
|
@ -368,15 +366,14 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
ty::Alias(_, alias_ty) => alias_ty,
|
ty::Alias(_, alias_ty) => alias_ty,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i, (assumption, _)) in self
|
for (assumption, _) in self
|
||||||
.tcx()
|
.tcx()
|
||||||
.bound_explicit_item_bounds(alias_ty.def_id)
|
.bound_explicit_item_bounds(alias_ty.def_id)
|
||||||
.subst_iter_copied(self.tcx(), alias_ty.substs)
|
.subst_iter_copied(self.tcx(), alias_ty.substs)
|
||||||
.enumerate()
|
|
||||||
{
|
{
|
||||||
match G::consider_assumption(self, goal, assumption) {
|
match G::consider_assumption(self, goal, assumption) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
candidates.push(Candidate { source: CandidateSource::AliasBound(i), result })
|
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
|
||||||
}
|
}
|
||||||
Err(NoSolution) => (),
|
Err(NoSolution) => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
(CandidateSource::Impl(_), _)
|
(CandidateSource::Impl(_), _)
|
||||||
| (CandidateSource::ParamEnv(_), _)
|
| (CandidateSource::ParamEnv(_), _)
|
||||||
| (CandidateSource::BuiltinImpl, _)
|
| (CandidateSource::BuiltinImpl, _)
|
||||||
| (CandidateSource::AliasBound(_), _) => unimplemented!(),
|
| (CandidateSource::AliasBound, _) => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -322,7 +322,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
match (candidate.source, other.source) {
|
match (candidate.source, other.source) {
|
||||||
(CandidateSource::Impl(_), _)
|
(CandidateSource::Impl(_), _)
|
||||||
| (CandidateSource::ParamEnv(_), _)
|
| (CandidateSource::ParamEnv(_), _)
|
||||||
| (CandidateSource::AliasBound(_), _)
|
| (CandidateSource::AliasBound, _)
|
||||||
| (CandidateSource::BuiltinImpl, _) => unimplemented!(),
|
| (CandidateSource::BuiltinImpl, _) => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
//! OS-specific networking functionality.
|
//! OS-specific networking functionality.
|
||||||
|
|
||||||
|
// See cfg macros in `library/std/src/os/mod.rs` for why these platforms must
|
||||||
|
// be special-cased during rustdoc generation.
|
||||||
|
#[cfg(not(all(
|
||||||
|
doc,
|
||||||
|
any(
|
||||||
|
all(target_arch = "wasm32", not(target_os = "wasi")),
|
||||||
|
all(target_vendor = "fortanix", target_env = "sgx")
|
||||||
|
)
|
||||||
|
)))]
|
||||||
#[cfg(any(target_os = "linux", target_os = "android", doc))]
|
#[cfg(any(target_os = "linux", target_os = "android", doc))]
|
||||||
pub(super) mod linux_ext;
|
pub(super) mod linux_ext;
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::ptr;
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_arch = "x86",
|
target_arch = "x86",
|
||||||
target_arch = "arm",
|
target_arch = "arm",
|
||||||
|
target_arch = "m68k",
|
||||||
target_arch = "mips",
|
target_arch = "mips",
|
||||||
target_arch = "powerpc",
|
target_arch = "powerpc",
|
||||||
target_arch = "powerpc64",
|
target_arch = "powerpc64",
|
||||||
|
|
|
@ -1431,6 +1431,13 @@ impl Build {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !stamp.exists() {
|
||||||
|
eprintln!(
|
||||||
|
"Warning: Unable to find the stamp file, did you try to keep a nonexistent build stage?"
|
||||||
|
);
|
||||||
|
crate::detail_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
let mut paths = Vec::new();
|
let mut paths = Vec::new();
|
||||||
let contents = t!(fs::read(stamp), &stamp);
|
let contents = t!(fs::read(stamp), &stamp);
|
||||||
// This is the method we use for extracting paths from the stamp file passed to us. See
|
// This is the method we use for extracting paths from the stamp file passed to us. See
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
fn main() {
|
||||||
|
let x = 42;
|
||||||
|
match x {
|
||||||
|
0..=73 => {},
|
||||||
|
74..=> {}, //~ ERROR unexpected `=>` after open range
|
||||||
|
//~^ ERROR expected one of `=>`, `if`, or `|`, found `>`
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
error: unexpected `=>` after open range
|
||||||
|
--> $DIR/half-open-range-pats-inclusive-match-arrow.rs:5:11
|
||||||
|
|
|
||||||
|
LL | 74..=> {},
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
help: add a space between the pattern and `=>`
|
||||||
|
|
|
||||||
|
LL | 74.. => {},
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected one of `=>`, `if`, or `|`, found `>`
|
||||||
|
--> $DIR/half-open-range-pats-inclusive-match-arrow.rs:5:14
|
||||||
|
|
|
||||||
|
LL | 74..=> {},
|
||||||
|
| ^ expected one of `=>`, `if`, or `|`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
19
tests/ui/mir/mir_codegen_ssa.rs
Normal file
19
tests/ui/mir/mir_codegen_ssa.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// build-pass
|
||||||
|
// compile-flags: --crate-type=lib
|
||||||
|
#![feature(custom_mir, core_intrinsics)]
|
||||||
|
use std::intrinsics::mir::*;
|
||||||
|
|
||||||
|
#[custom_mir(dialect = "runtime", phase = "optimized")]
|
||||||
|
pub fn f(a: u32) -> u32 {
|
||||||
|
mir!(
|
||||||
|
let x: u32;
|
||||||
|
{
|
||||||
|
// Previously code generation failed with ICE "use of .. before def ..." because the
|
||||||
|
// definition of x was incorrectly identified as dominating the use of x located in the
|
||||||
|
// same statement:
|
||||||
|
x = x + a;
|
||||||
|
RET = x;
|
||||||
|
Return()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
11
tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.fixed
Normal file
11
tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.fixed
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// run-rustfix
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
fn foo(_: &mut ()) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut uwu = ();
|
||||||
|
let mut r = Pin::new(&mut uwu);
|
||||||
|
foo(r.as_mut().get_mut());
|
||||||
|
foo(r.get_mut()); //~ ERROR use of moved value
|
||||||
|
}
|
11
tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.rs
Normal file
11
tests/ui/moves/pin-mut-reborrow-infer-var-issue-107419.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// run-rustfix
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
fn foo(_: &mut ()) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut uwu = ();
|
||||||
|
let mut r = Pin::new(&mut uwu);
|
||||||
|
foo(r.get_mut());
|
||||||
|
foo(r.get_mut()); //~ ERROR use of moved value
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
error[E0382]: use of moved value: `r`
|
||||||
|
--> $DIR/pin-mut-reborrow-infer-var-issue-107419.rs:10:9
|
||||||
|
|
|
||||||
|
LL | let mut r = Pin::new(&mut uwu);
|
||||||
|
| ----- move occurs because `r` has type `Pin<&mut ()>`, which does not implement the `Copy` trait
|
||||||
|
LL | foo(r.get_mut());
|
||||||
|
| --------- `r` moved due to this method call
|
||||||
|
LL | foo(r.get_mut());
|
||||||
|
| ^ value used here after move
|
||||||
|
|
|
||||||
|
note: `Pin::<&'a mut T>::get_mut` takes ownership of the receiver `self`, which moves `r`
|
||||||
|
--> $SRC_DIR/core/src/pin.rs:LL:COL
|
||||||
|
help: consider reborrowing the `Pin` instead of moving it
|
||||||
|
|
|
||||||
|
LL | foo(r.as_mut().get_mut());
|
||||||
|
| +++++++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0382`.
|
Loading…
Add table
Add a link
Reference in a new issue