Rollup merge of #107467 - WaffleLapkin:uneq, r=oli-obk

Improve enum checks

Some light refactoring.
This commit is contained in:
Guillaume Gomez 2023-01-31 23:38:52 +01:00 committed by GitHub
commit 53bb6322db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 278 additions and 260 deletions

View File

@ -58,23 +58,24 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol {
// In case we have doc comments like `/**` or `/*!`, we want to remove stars if they are // In case we have doc comments like `/**` or `/*!`, we want to remove stars if they are
// present. However, we first need to strip the empty lines so they don't get in the middle // present. However, we first need to strip the empty lines so they don't get in the middle
// when we try to compute the "horizontal trim". // when we try to compute the "horizontal trim".
let lines = if kind == CommentKind::Block { let lines = match kind {
// Whatever happens, we skip the first line. CommentKind::Block => {
let mut i = lines // Whatever happens, we skip the first line.
.get(0) let mut i = lines
.map(|l| if l.trim_start().starts_with('*') { 0 } else { 1 }) .get(0)
.unwrap_or(0); .map(|l| if l.trim_start().starts_with('*') { 0 } else { 1 })
let mut j = lines.len(); .unwrap_or(0);
let mut j = lines.len();
while i < j && lines[i].trim().is_empty() { while i < j && lines[i].trim().is_empty() {
i += 1; i += 1;
}
while j > i && lines[j - 1].trim().is_empty() {
j -= 1;
}
&lines[i..j]
} }
while j > i && lines[j - 1].trim().is_empty() { CommentKind::Line => lines,
j -= 1;
}
&lines[i..j]
} else {
lines
}; };
for line in lines { for line in lines {

View File

@ -344,7 +344,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} else { } else {
err.span_help(source_info.span, "try removing `&mut` here"); err.span_help(source_info.span, "try removing `&mut` here");
} }
} else if decl.mutability == Mutability::Not { } else if decl.mutability.is_not() {
if matches!( if matches!(
decl.local_info, decl.local_info,
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf( Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(

View File

@ -2028,7 +2028,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
}; };
if ty_to_mut == Mutability::Mut && ty_mut == Mutability::Not { if ty_to_mut.is_mut() && ty_mut.is_not() {
span_mirbug!( span_mirbug!(
self, self,
rvalue, rvalue,

View File

@ -622,10 +622,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
let alloc = alloc.inner(); let alloc = alloc.inner();
if is_write { if is_write {
// Write access. These are never allowed, but we give a targeted error message. // Write access. These are never allowed, but we give a targeted error message.
if alloc.mutability == Mutability::Not { match alloc.mutability {
Err(err_ub!(WriteToReadOnly(alloc_id)).into()) Mutability::Not => Err(err_ub!(WriteToReadOnly(alloc_id)).into()),
} else { Mutability::Mut => Err(ConstEvalErrKind::ModifiedGlobal.into()),
Err(ConstEvalErrKind::ModifiedGlobal.into())
} }
} else { } else {
// Read access. These are usually allowed, with some exceptions. // Read access. These are usually allowed, with some exceptions.

View File

@ -304,7 +304,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
.into()); .into());
}; };
if alloc.mutability == Mutability::Not { if alloc.mutability.is_not() {
throw_ub_format!("deallocating immutable allocation {alloc_id:?}"); throw_ub_format!("deallocating immutable allocation {alloc_id:?}");
} }
if alloc_kind != kind { if alloc_kind != kind {
@ -631,7 +631,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
let (_kind, alloc) = self.memory.alloc_map.get_mut(id).unwrap(); let (_kind, alloc) = self.memory.alloc_map.get_mut(id).unwrap();
if alloc.mutability == Mutability::Not { if alloc.mutability.is_not() {
throw_ub!(WriteToReadOnly(id)) throw_ub!(WriteToReadOnly(id))
} }
Ok((alloc, &mut self.machine)) Ok((alloc, &mut self.machine))

View File

@ -754,7 +754,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
// FIXME(JakobDegen) The validator should check that `self.mir_phase < // FIXME(JakobDegen) The validator should check that `self.mir_phase <
// DropsLowered`. However, this causes ICEs with generation of drop shims, which // DropsLowered`. However, this causes ICEs with generation of drop shims, which
// seem to fail to set their `MirPhase` correctly. // seem to fail to set their `MirPhase` correctly.
if *kind == RetagKind::Raw || *kind == RetagKind::TwoPhase { if matches!(kind, RetagKind::Raw | RetagKind::TwoPhase) {
self.fail(location, format!("explicit `{:?}` is forbidden", kind)); self.fail(location, format!("explicit `{:?}` is forbidden", kind));
} }
} }

View File

@ -2113,30 +2113,38 @@ impl EmitterWriter {
} }
} }
for sugg in suggestions { for sugg in suggestions {
if sugg.style == SuggestionStyle::CompletelyHidden { match sugg.style {
// do not display this suggestion, it is meant only for tools SuggestionStyle::CompletelyHidden => {
} else if sugg.style == SuggestionStyle::HideCodeAlways { // do not display this suggestion, it is meant only for tools
if let Err(e) = self.emit_message_default(
&MultiSpan::new(),
&[(sugg.msg.to_owned(), Style::HeaderMsg)],
args,
&None,
&Level::Help,
max_line_num_len,
true,
None,
) {
panic!("failed to emit error: {}", e);
} }
} else if let Err(e) = self.emit_suggestion_default( SuggestionStyle::HideCodeAlways => {
span, if let Err(e) = self.emit_message_default(
sugg, &MultiSpan::new(),
args, &[(sugg.msg.to_owned(), Style::HeaderMsg)],
&Level::Help, args,
max_line_num_len, &None,
) { &Level::Help,
panic!("failed to emit error: {}", e); max_line_num_len,
}; true,
None,
) {
panic!("failed to emit error: {}", e);
}
}
SuggestionStyle::HideCodeInline
| SuggestionStyle::ShowCode
| SuggestionStyle::ShowAlways => {
if let Err(e) = self.emit_suggestion_default(
span,
sugg,
args,
&Level::Help,
max_line_num_len,
) {
panic!("failed to emit error: {}", e);
}
}
}
} }
} }
} }

View File

@ -142,7 +142,7 @@ impl StyledBuffer {
pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) { pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
if let Some(ref mut line) = self.lines.get_mut(line) { if let Some(ref mut line) = self.lines.get_mut(line) {
if let Some(StyledChar { style: s, .. }) = line.get_mut(col) { if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
if overwrite || *s == Style::NoStyle || *s == Style::Quotation { if overwrite || matches!(s, Style::NoStyle | Style::Quotation) {
*s = style; *s = style;
} }
} }

View File

@ -503,7 +503,7 @@ impl TtParser {
mp.push_match(metavar_idx, seq_depth, MatchedSeq(vec![])); mp.push_match(metavar_idx, seq_depth, MatchedSeq(vec![]));
} }
if op == KleeneOp::ZeroOrMore || op == KleeneOp::ZeroOrOne { if matches!(op, KleeneOp::ZeroOrMore | KleeneOp::ZeroOrOne) {
// Try zero matches of this sequence, by skipping over it. // Try zero matches of this sequence, by skipping over it.
self.cur_mps.push(MatcherPos { self.cur_mps.push(MatcherPos {
idx: idx_first_after, idx: idx_first_after,

View File

@ -385,10 +385,9 @@ pub fn check_generic_arg_count_for_call(
) -> GenericArgCountResult { ) -> GenericArgCountResult {
let empty_args = hir::GenericArgs::none(); let empty_args = hir::GenericArgs::none();
let gen_args = seg.args.unwrap_or(&empty_args); let gen_args = seg.args.unwrap_or(&empty_args);
let gen_pos = if is_method_call == IsMethodCall::Yes { let gen_pos = match is_method_call {
GenericArgPosition::MethodCall IsMethodCall::Yes => GenericArgPosition::MethodCall,
} else { IsMethodCall::No => GenericArgPosition::Value,
GenericArgPosition::Value
}; };
let has_self = generics.parent.is_none() && generics.has_self; let has_self = generics.parent.is_none() && generics.has_self;

View File

@ -606,59 +606,66 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
}; };
check_abi(tcx, it.hir_id(), it.span, abi); check_abi(tcx, it.hir_id(), it.span, abi);
if abi == Abi::RustIntrinsic { match abi {
for item in items { Abi::RustIntrinsic => {
let item = tcx.hir().foreign_item(item.id); for item in items {
intrinsic::check_intrinsic_type(tcx, item); let item = tcx.hir().foreign_item(item.id);
} intrinsic::check_intrinsic_type(tcx, item);
} else if abi == Abi::PlatformIntrinsic {
for item in items {
let item = tcx.hir().foreign_item(item.id);
intrinsic::check_platform_intrinsic_type(tcx, item);
}
} else {
for item in items {
let def_id = item.id.owner_id.def_id;
let generics = tcx.generics_of(def_id);
let own_counts = generics.own_counts();
if generics.params.len() - own_counts.lifetimes != 0 {
let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
(_, 0) => ("type", "types", Some("u32")),
// We don't specify an example value, because we can't generate
// a valid value for any type.
(0, _) => ("const", "consts", None),
_ => ("type or const", "types or consts", None),
};
struct_span_err!(
tcx.sess,
item.span,
E0044,
"foreign items may not have {kinds} parameters",
)
.span_label(item.span, &format!("can't have {kinds} parameters"))
.help(
// FIXME: once we start storing spans for type arguments, turn this
// into a suggestion.
&format!(
"replace the {} parameters with concrete {}{}",
kinds,
kinds_pl,
egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
),
)
.emit();
} }
}
let item = tcx.hir().foreign_item(item.id); Abi::PlatformIntrinsic => {
match &item.kind { for item in items {
hir::ForeignItemKind::Fn(fn_decl, _, _) => { let item = tcx.hir().foreign_item(item.id);
require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span); intrinsic::check_platform_intrinsic_type(tcx, item);
}
}
_ => {
for item in items {
let def_id = item.id.owner_id.def_id;
let generics = tcx.generics_of(def_id);
let own_counts = generics.own_counts();
if generics.params.len() - own_counts.lifetimes != 0 {
let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts)
{
(_, 0) => ("type", "types", Some("u32")),
// We don't specify an example value, because we can't generate
// a valid value for any type.
(0, _) => ("const", "consts", None),
_ => ("type or const", "types or consts", None),
};
struct_span_err!(
tcx.sess,
item.span,
E0044,
"foreign items may not have {kinds} parameters",
)
.span_label(item.span, &format!("can't have {kinds} parameters"))
.help(
// FIXME: once we start storing spans for type arguments, turn this
// into a suggestion.
&format!(
"replace the {} parameters with concrete {}{}",
kinds,
kinds_pl,
egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
),
)
.emit();
} }
hir::ForeignItemKind::Static(..) => {
check_static_inhabited(tcx, def_id); let item = tcx.hir().foreign_item(item.id);
check_static_linkage(tcx, def_id); match &item.kind {
hir::ForeignItemKind::Fn(fn_decl, _, _) => {
require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span);
}
hir::ForeignItemKind::Static(..) => {
check_static_inhabited(tcx, def_id);
check_static_linkage(tcx, def_id);
}
_ => {}
} }
_ => {}
} }
} }
} }

View File

@ -9,9 +9,7 @@ use rustc_ast_pretty::pp::{self, Breaks};
use rustc_ast_pretty::pprust::{Comments, PrintState}; use rustc_ast_pretty::pprust::{Comments, PrintState};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::LifetimeParamKind; use rustc_hir::LifetimeParamKind;
use rustc_hir::{ use rustc_hir::{BindingAnnotation, ByRef, GenericArg, GenericParam, GenericParamKind, Node, Term};
BindingAnnotation, ByRef, GenericArg, GenericParam, GenericParamKind, Mutability, Node, Term,
};
use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}; use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
use rustc_span::source_map::SourceMap; use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol}; use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol};
@ -1746,7 +1744,7 @@ impl<'a> State<'a> {
if by_ref == ByRef::Yes { if by_ref == ByRef::Yes {
self.word_nbsp("ref"); self.word_nbsp("ref");
} }
if mutbl == Mutability::Mut { if mutbl.is_mut() {
self.word_nbsp("mut"); self.word_nbsp("mut");
} }
self.print_ident(ident); self.print_ident(ident);

View File

@ -1354,13 +1354,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
return Some(Err(MethodError::Ambiguity(sources))); return Some(Err(MethodError::Ambiguity(sources)));
} }
applicable_candidates.pop().map(|(probe, status)| { applicable_candidates.pop().map(|(probe, status)| match status {
if status == ProbeResult::Match { ProbeResult::Match => {
Ok(probe Ok(probe
.to_unadjusted_pick(self_ty, unstable_candidates.cloned().unwrap_or_default())) .to_unadjusted_pick(self_ty, unstable_candidates.cloned().unwrap_or_default()))
} else {
Err(MethodError::BadReturnType)
} }
ProbeResult::NoMatch | ProbeResult::BadReturnType => Err(MethodError::BadReturnType),
}) })
} }
} }

View File

@ -580,27 +580,28 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
} }
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) { fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
// If the method is an impl for a trait, don't doc.
let context = method_context(cx, impl_item.owner_id.def_id); let context = method_context(cx, impl_item.owner_id.def_id);
if context == MethodLateContext::TraitImpl {
return;
}
// If the method is an impl for an item with docs_hidden, don't doc. match context {
if context == MethodLateContext::PlainImpl { // If the method is an impl for a trait, don't doc.
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()); MethodLateContext::TraitImpl => return,
let impl_ty = cx.tcx.type_of(parent); MethodLateContext::TraitAutoImpl => {}
let outerdef = match impl_ty.kind() { // If the method is an impl for an item with docs_hidden, don't doc.
ty::Adt(def, _) => Some(def.did()), MethodLateContext::PlainImpl => {
ty::Foreign(def_id) => Some(*def_id), let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id());
_ => None, let impl_ty = cx.tcx.type_of(parent);
}; let outerdef = match impl_ty.kind() {
let is_hidden = match outerdef { ty::Adt(def, _) => Some(def.did()),
Some(id) => cx.tcx.is_doc_hidden(id), ty::Foreign(def_id) => Some(*def_id),
None => false, _ => None,
}; };
if is_hidden { let is_hidden = match outerdef {
return; Some(id) => cx.tcx.is_doc_hidden(id),
None => false,
};
if is_hidden {
return;
}
} }
} }

View File

@ -113,37 +113,37 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
CrateType::Staticlib => Linkage::Static, CrateType::Staticlib => Linkage::Static,
}; };
if preferred_linkage == Linkage::NotLinked { match preferred_linkage {
// If the crate is not linked, there are no link-time dependencies. // If the crate is not linked, there are no link-time dependencies.
return Vec::new(); Linkage::NotLinked => return Vec::new(),
} Linkage::Static => {
// Attempt static linkage first. For dylibs and executables, we may be
if preferred_linkage == Linkage::Static { // able to retry below with dynamic linkage.
// Attempt static linkage first. For dylibs and executables, we may be if let Some(v) = attempt_static(tcx) {
// able to retry below with dynamic linkage. return v;
if let Some(v) = attempt_static(tcx) { }
return v;
} // Staticlibs and static executables must have all static dependencies.
// If any are not found, generate some nice pretty errors.
// Staticlibs and static executables must have all static dependencies. if ty == CrateType::Staticlib
// If any are not found, generate some nice pretty errors. || (ty == CrateType::Executable
if ty == CrateType::Staticlib && sess.crt_static(Some(ty))
|| (ty == CrateType::Executable && !sess.target.crt_static_allows_dylibs)
&& sess.crt_static(Some(ty)) {
&& !sess.target.crt_static_allows_dylibs) for &cnum in tcx.crates(()).iter() {
{ if tcx.dep_kind(cnum).macros_only() {
for &cnum in tcx.crates(()).iter() { continue;
if tcx.dep_kind(cnum).macros_only() { }
continue; let src = tcx.used_crate_source(cnum);
} if src.rlib.is_some() {
let src = tcx.used_crate_source(cnum); continue;
if src.rlib.is_some() { }
continue; sess.emit_err(RlibRequired { crate_name: tcx.crate_name(cnum) });
} }
sess.emit_err(RlibRequired { crate_name: tcx.crate_name(cnum) }); return Vec::new();
} }
return Vec::new();
} }
Linkage::Dynamic | Linkage::IncludedFromDylib => {}
} }
let mut formats = FxHashMap::default(); let mut formats = FxHashMap::default();
@ -283,12 +283,9 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
let mut ret = tcx let mut ret = tcx
.crates(()) .crates(())
.iter() .iter()
.map(|&cnum| { .map(|&cnum| match tcx.dep_kind(cnum) {
if tcx.dep_kind(cnum) == CrateDepKind::Explicit { CrateDepKind::Explicit => Linkage::Static,
Linkage::Static CrateDepKind::MacrosOnly | CrateDepKind::Implicit => Linkage::NotLinked,
} else {
Linkage::NotLinked
}
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View File

@ -107,7 +107,7 @@ impl<'tcx> Collector<'tcx> {
return; return;
}; };
if abi == Abi::Rust || abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { if matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic) {
return; return;
} }

View File

@ -135,7 +135,10 @@ impl Debug for CoverageKind {
"Expression({:?}) = {} {} {}", "Expression({:?}) = {} {} {}",
id.index(), id.index(),
lhs.index(), lhs.index(),
if *op == Op::Add { "+" } else { "-" }, match op {
Op::Add => "+",
Op::Subtract => "-",
},
rhs.index(), rhs.index(),
), ),
Unreachable => write!(fmt, "Unreachable"), Unreachable => write!(fmt, "Unreachable"),

View File

@ -110,7 +110,7 @@ fn write_graph_label<'tcx, W: std::fmt::Write>(
let decl = &body.local_decls[local]; let decl = &body.local_decls[local];
write!(w, "let ")?; write!(w, "let ")?;
if decl.mutability == Mutability::Mut { if decl.mutability.is_mut() {
write!(w, "mut ")?; write!(w, "mut ")?;
} }

View File

@ -416,11 +416,7 @@ impl<'tcx> Body<'tcx> {
(self.arg_count + 1..self.local_decls.len()).filter_map(move |index| { (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
let local = Local::new(index); let local = Local::new(index);
let decl = &self.local_decls[local]; let decl = &self.local_decls[local];
if decl.is_user_variable() && decl.mutability == Mutability::Mut { (decl.is_user_variable() && decl.mutability.is_mut()).then(|| local)
Some(local)
} else {
None
}
}) })
} }

View File

@ -580,7 +580,7 @@ fn write_scope_tree(
continue; continue;
} }
let mut_str = if local_decl.mutability == Mutability::Mut { "mut " } else { "" }; let mut_str = local_decl.mutability.prefix_str();
let mut indented_decl = let mut indented_decl =
format!("{0:1$}let {2}{3:?}: {4:?}", INDENT, indent, mut_str, local, local_decl.ty); format!("{0:1$}let {2}{3:?}: {4:?}", INDENT, indent, mut_str, local, local_decl.ty);

View File

@ -44,7 +44,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let expr_ty = expr.ty; let expr_ty = expr.ty;
let temp = { let temp = {
let mut local_decl = LocalDecl::new(expr_ty, expr_span); let mut local_decl = LocalDecl::new(expr_ty, expr_span);
if mutability == Mutability::Not { if mutability.is_not() {
local_decl = local_decl.immutable(); local_decl = local_decl.immutable();
} }

View File

@ -5,7 +5,6 @@ use std::cell::Cell;
use either::Right; use either::Right;
use rustc_ast::Mutability;
use rustc_const_eval::const_eval::CheckAlignment; use rustc_const_eval::const_eval::CheckAlignment;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
@ -289,7 +288,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
} }
// If the static allocation is mutable, then we can't const prop it as its content // If the static allocation is mutable, then we can't const prop it as its content
// might be different at runtime. // might be different at runtime.
if alloc.inner().mutability == Mutability::Mut { if alloc.inner().mutability.is_mut() {
throw_machine_stop_str!("can't access mutable globals in ConstProp"); throw_machine_stop_str!("can't access mutable globals in ConstProp");
} }
@ -528,7 +527,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
let r = self.use_ecx(|this| this.ecx.read_immediate(&this.ecx.eval_operand(right, None)?)); let r = self.use_ecx(|this| this.ecx.read_immediate(&this.ecx.eval_operand(right, None)?));
let l = self.use_ecx(|this| this.ecx.read_immediate(&this.ecx.eval_operand(left, None)?)); let l = self.use_ecx(|this| this.ecx.read_immediate(&this.ecx.eval_operand(left, None)?));
// Check for exceeding shifts *even if* we cannot evaluate the LHS. // Check for exceeding shifts *even if* we cannot evaluate the LHS.
if op == BinOp::Shr || op == BinOp::Shl { if matches!(op, BinOp::Shr | BinOp::Shl) {
let r = r.clone()?; let r = r.clone()?;
// We need the type of the LHS. We cannot use `place_layout` as that is the type // We need the type of the LHS. We cannot use `place_layout` as that is the type
// of the result, which for checked binops is not the same! // of the result, which for checked binops is not the same!

View File

@ -368,7 +368,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
this.ecx.read_immediate(&this.ecx.eval_operand(left, None)?) this.ecx.read_immediate(&this.ecx.eval_operand(left, None)?)
}); });
// Check for exceeding shifts *even if* we cannot evaluate the LHS. // Check for exceeding shifts *even if* we cannot evaluate the LHS.
if op == BinOp::Shr || op == BinOp::Shl { if matches!(op, BinOp::Shr | BinOp::Shl) {
let r = r.clone()?; let r = r.clone()?;
// We need the type of the LHS. We cannot use `place_layout` as that is the type // We need the type of the LHS. We cannot use `place_layout` as that is the type
// of the result, which for checked binops is not the same! // of the result, which for checked binops is not the same!

View File

@ -323,7 +323,10 @@ impl DebugCounters {
String::new() String::new()
}, },
self.format_operand(lhs), self.format_operand(lhs),
if op == Op::Add { "+" } else { "-" }, match op {
Op::Add => "+",
Op::Subtract => "-",
},
self.format_operand(rhs), self.format_operand(rhs),
); );
} }

View File

@ -427,7 +427,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
fn make_place(&mut self, mutability: Mutability, ty: Ty<'tcx>) -> Place<'tcx> { fn make_place(&mut self, mutability: Mutability, ty: Ty<'tcx>) -> Place<'tcx> {
let span = self.span; let span = self.span;
let mut local = LocalDecl::new(ty, span); let mut local = LocalDecl::new(ty, span);
if mutability == Mutability::Not { if mutability.is_not() {
local = local.immutable(); local = local.immutable();
} }
Place::from(self.local_decls.push(local)) Place::from(self.local_decls.push(local))

View File

@ -93,11 +93,12 @@ impl<'a> Parser<'a> {
// or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
// that starts like a path (1 token), but it fact not a path. // that starts like a path (1 token), but it fact not a path.
// Also, we avoid stealing syntax from `parse_item_`. // Also, we avoid stealing syntax from `parse_item_`.
if force_collect == ForceCollect::Yes { match force_collect {
self.collect_tokens_no_attrs(|this| this.parse_stmt_path_start(lo, attrs)) ForceCollect::Yes => {
} else { self.collect_tokens_no_attrs(|this| this.parse_stmt_path_start(lo, attrs))?
self.parse_stmt_path_start(lo, attrs) }
}? ForceCollect::No => self.parse_stmt_path_start(lo, attrs)?,
}
} else if let Some(item) = self.parse_item_common( } else if let Some(item) = self.parse_item_common(
attrs.clone(), attrs.clone(),
false, false,
@ -113,13 +114,12 @@ impl<'a> Parser<'a> {
self.mk_stmt(lo, StmtKind::Empty) self.mk_stmt(lo, StmtKind::Empty)
} else if self.token != token::CloseDelim(Delimiter::Brace) { } else if self.token != token::CloseDelim(Delimiter::Brace) {
// Remainder are line-expr stmts. // Remainder are line-expr stmts.
let e = if force_collect == ForceCollect::Yes { let e = match force_collect {
self.collect_tokens_no_attrs(|this| { ForceCollect::Yes => self.collect_tokens_no_attrs(|this| {
this.parse_expr_res(Restrictions::STMT_EXPR, Some(attrs)) this.parse_expr_res(Restrictions::STMT_EXPR, Some(attrs))
}) })?,
} else { ForceCollect::No => self.parse_expr_res(Restrictions::STMT_EXPR, Some(attrs))?,
self.parse_expr_res(Restrictions::STMT_EXPR, Some(attrs)) };
}?;
if matches!(e.kind, ExprKind::Assign(..)) && self.eat_keyword(kw::Else) { if matches!(e.kind, ExprKind::Assign(..)) && self.eat_keyword(kw::Else) {
let bl = self.parse_block()?; let bl = self.parse_block()?;
// Destructuring assignment ... else. // Destructuring assignment ... else.

View File

@ -323,13 +323,14 @@ impl<'a> Parser<'a> {
} else if self.can_begin_bound() { } else if self.can_begin_bound() {
self.parse_bare_trait_object(lo, allow_plus)? self.parse_bare_trait_object(lo, allow_plus)?
} else if self.eat(&token::DotDotDot) { } else if self.eat(&token::DotDotDot) {
if allow_c_variadic == AllowCVariadic::Yes { match allow_c_variadic {
TyKind::CVarArgs AllowCVariadic::Yes => TyKind::CVarArgs,
} else { AllowCVariadic::No => {
// FIXME(Centril): Should we just allow `...` syntactically // FIXME(Centril): Should we just allow `...` syntactically
// anywhere in a type and use semantic restrictions instead? // anywhere in a type and use semantic restrictions instead?
self.error_illegal_c_varadic_ty(lo); self.error_illegal_c_varadic_ty(lo);
TyKind::Err TyKind::Err
}
} }
} else { } else {
let msg = format!("expected type, found {}", super::token_descr(&self.token)); let msg = format!("expected type, found {}", super::token_descr(&self.token));
@ -343,10 +344,9 @@ impl<'a> Parser<'a> {
let mut ty = self.mk_ty(span, kind); let mut ty = self.mk_ty(span, kind);
// Try to recover from use of `+` with incorrect priority. // Try to recover from use of `+` with incorrect priority.
if allow_plus == AllowPlus::Yes { match allow_plus {
self.maybe_recover_from_bad_type_plus(&ty)?; AllowPlus::Yes => self.maybe_recover_from_bad_type_plus(&ty)?,
} else { AllowPlus::No => self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty),
self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty);
} }
if RecoverQuestionMark::Yes == recover_question_mark { if RecoverQuestionMark::Yes == recover_question_mark {
ty = self.maybe_recover_from_question_mark(ty); ty = self.maybe_recover_from_question_mark(ty);

View File

@ -864,33 +864,39 @@ impl CheckAttrVisitor<'_> {
target: Target, target: Target,
specified_inline: &mut Option<(bool, Span)>, specified_inline: &mut Option<(bool, Span)>,
) -> bool { ) -> bool {
if target == Target::Use || target == Target::ExternCrate { match target {
let do_inline = meta.name_or_empty() == sym::inline; Target::Use | Target::ExternCrate => {
if let Some((prev_inline, prev_span)) = *specified_inline { let do_inline = meta.name_or_empty() == sym::inline;
if do_inline != prev_inline { if let Some((prev_inline, prev_span)) = *specified_inline {
let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]); if do_inline != prev_inline {
spans.push_span_label(prev_span, fluent::passes_doc_inline_conflict_first); let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]);
spans.push_span_label(meta.span(), fluent::passes_doc_inline_conflict_second); spans.push_span_label(prev_span, fluent::passes_doc_inline_conflict_first);
self.tcx.sess.emit_err(errors::DocKeywordConflict { spans }); spans.push_span_label(
return false; meta.span(),
fluent::passes_doc_inline_conflict_second,
);
self.tcx.sess.emit_err(errors::DocKeywordConflict { spans });
return false;
}
true
} else {
*specified_inline = Some((do_inline, meta.span()));
true
} }
true
} else {
*specified_inline = Some((do_inline, meta.span()));
true
} }
} else { _ => {
self.tcx.emit_spanned_lint( self.tcx.emit_spanned_lint(
INVALID_DOC_ATTRIBUTES, INVALID_DOC_ATTRIBUTES,
hir_id, hir_id,
meta.span(), meta.span(),
errors::DocInlineOnlyUse { errors::DocInlineOnlyUse {
attr_span: meta.span(), attr_span: meta.span(),
item_span: (attr.style == AttrStyle::Outer) item_span: (attr.style == AttrStyle::Outer)
.then(|| self.tcx.hir().span(hir_id)), .then(|| self.tcx.hir().span(hir_id)),
}, },
); );
false false
}
} }
} }
@ -1137,7 +1143,7 @@ impl CheckAttrVisitor<'_> {
errors::DocTestUnknownInclude { errors::DocTestUnknownInclude {
path, path,
value: value.to_string(), value: value.to_string(),
inner: if attr.style == AttrStyle::Inner { "!" } else { "" }, inner: match attr.style { AttrStyle::Inner=> "!" , AttrStyle::Outer => "" },
sugg: (attr.meta().unwrap().span, applicability), sugg: (attr.meta().unwrap().span, applicability),
} }
); );

View File

@ -125,7 +125,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
if let Some((depr, span)) = &depr { if let Some((depr, span)) = &depr {
is_deprecated = true; is_deprecated = true;
if kind == AnnotationKind::Prohibited || kind == AnnotationKind::DeprecationProhibited { if matches!(kind, AnnotationKind::Prohibited | AnnotationKind::DeprecationProhibited) {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
self.tcx.emit_spanned_lint( self.tcx.emit_spanned_lint(
USELESS_DEPRECATED, USELESS_DEPRECATED,

View File

@ -298,14 +298,15 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
self.r.record_partial_res(id, PartialRes::new(res)); self.r.record_partial_res(id, PartialRes::new(res));
} }
if module.is_normal() { if module.is_normal() {
if res == Res::Err { match res {
Ok(ty::Visibility::Public) Res::Err => Ok(ty::Visibility::Public),
} else { _ => {
let vis = ty::Visibility::Restricted(res.def_id()); let vis = ty::Visibility::Restricted(res.def_id());
if self.r.is_accessible_from(vis, parent_scope.module) { if self.r.is_accessible_from(vis, parent_scope.module) {
Ok(vis.expect_local()) Ok(vis.expect_local())
} else { } else {
Err(VisResolutionError::AncestorOnly(path.span)) Err(VisResolutionError::AncestorOnly(path.span))
}
} }
} }
} else { } else {

View File

@ -1552,12 +1552,12 @@ impl<'a> Resolver<'a> {
if b.is_extern_crate() && ident.span.rust_2018() { if b.is_extern_crate() && ident.span.rust_2018() {
help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously")) help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously"))
} }
if misc == AmbiguityErrorMisc::SuggestCrate { match misc {
help_msgs AmbiguityErrorMisc::SuggestCrate => help_msgs
.push(format!("use `crate::{ident}` to refer to this {thing} unambiguously")) .push(format!("use `crate::{ident}` to refer to this {thing} unambiguously")),
} else if misc == AmbiguityErrorMisc::SuggestSelf { AmbiguityErrorMisc::SuggestSelf => help_msgs
help_msgs .push(format!("use `self::{ident}` to refer to this {thing} unambiguously")),
.push(format!("use `self::{ident}` to refer to this {thing} unambiguously")) AmbiguityErrorMisc::FromPrelude | AmbiguityErrorMisc::None => {}
} }
err.span_note(b.span, &note_msg); err.span_note(b.span, &note_msg);

View File

@ -29,7 +29,6 @@ use crate::{id_from_def_id, SaveContext};
use rls_data::{SigElement, Signature}; use rls_data::{SigElement, Signature};
use rustc_ast::Mutability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir_pretty::id_to_string; use rustc_hir_pretty::id_to_string;
@ -769,9 +768,8 @@ impl<'hir> Sig for hir::ForeignItem<'hir> {
} }
hir::ForeignItemKind::Static(ref ty, m) => { hir::ForeignItemKind::Static(ref ty, m) => {
let mut text = "static ".to_owned(); let mut text = "static ".to_owned();
if m == Mutability::Mut { text.push_str(m.prefix_str());
text.push_str("mut ");
}
let name = self.ident.to_string(); let name = self.ident.to_string();
let defs = vec![SigElement { let defs = vec![SigElement {
id: id_from_def_id(self.owner_id.to_def_id()), id: id_from_def_id(self.owner_id.to_def_id()),

View File

@ -1230,20 +1230,23 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
} }
ty::PredicateKind::WellFormed(ty) => { ty::PredicateKind::WellFormed(ty) => {
if self.tcx.sess.opts.unstable_opts.trait_solver == TraitSolver::Classic { match self.tcx.sess.opts.unstable_opts.trait_solver {
// WF predicates cannot themselves make TraitSolver::Classic => {
// errors. They can only block due to // WF predicates cannot themselves make
// ambiguity; otherwise, they always // errors. They can only block due to
// degenerate into other obligations // ambiguity; otherwise, they always
// (which may fail). // degenerate into other obligations
span_bug!(span, "WF predicate not satisfied for {:?}", ty); // (which may fail).
} else { span_bug!(span, "WF predicate not satisfied for {:?}", ty);
// FIXME: we'll need a better message which takes into account }
// which bounds actually failed to hold. TraitSolver::Chalk | TraitSolver::Next => {
self.tcx.sess.struct_span_err( // FIXME: we'll need a better message which takes into account
span, // which bounds actually failed to hold.
&format!("the type `{}` is not well-formed", ty), self.tcx.sess.struct_span_err(
) span,
&format!("the type `{}` is not well-formed", ty),
)
}
} }
} }