Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve enum checks #107467

Merged
merged 4 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions compiler/rustc_ast/src/util/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// 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".
let lines = if kind == CommentKind::Block {
// Whatever happens, we skip the first line.
let mut i = lines
.get(0)
.map(|l| if l.trim_start().starts_with('*') { 0 } else { 1 })
.unwrap_or(0);
let mut j = lines.len();

while i < j && lines[i].trim().is_empty() {
i += 1;
}
while j > i && lines[j - 1].trim().is_empty() {
j -= 1;
let lines = match kind {
CommentKind::Block => {
// Whatever happens, we skip the first line.
let mut i = lines
.get(0)
.map(|l| if l.trim_start().starts_with('*') { 0 } else { 1 })
.unwrap_or(0);
let mut j = lines.len();

while i < j && lines[i].trim().is_empty() {
i += 1;
}
while j > i && lines[j - 1].trim().is_empty() {
j -= 1;
}
&lines[i..j]
}
&lines[i..j]
} else {
lines
CommentKind::Line => lines,
};

for line in lines {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} else {
err.span_help(source_info.span, "try removing `&mut` here");
}
} else if decl.mutability == Mutability::Not {
} else if decl.mutability.is_not() {
if matches!(
decl.local_info,
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
self,
rvalue,
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,10 +622,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
let alloc = alloc.inner();
if is_write {
// Write access. These are never allowed, but we give a targeted error message.
if alloc.mutability == Mutability::Not {
Err(err_ub!(WriteToReadOnly(alloc_id)).into())
} else {
Err(ConstEvalErrKind::ModifiedGlobal.into())
match alloc.mutability {
Mutability::Not => Err(err_ub!(WriteToReadOnly(alloc_id)).into()),
Mutability::Mut => Err(ConstEvalErrKind::ModifiedGlobal.into()),
}
} else {
// Read access. These are usually allowed, with some exceptions.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
.into());
};

if alloc.mutability == Mutability::Not {
if alloc.mutability.is_not() {
throw_ub_format!("deallocating immutable allocation {alloc_id:?}");
}
if alloc_kind != kind {
Expand Down Expand Up @@ -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();
if alloc.mutability == Mutability::Not {
if alloc.mutability.is_not() {
throw_ub!(WriteToReadOnly(id))
}
Ok((alloc, &mut self.machine))
Expand Down
54 changes: 31 additions & 23 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2113,30 +2113,38 @@ impl EmitterWriter {
}
}
for sugg in suggestions {
if sugg.style == SuggestionStyle::CompletelyHidden {
// do not display this suggestion, it is meant only for tools
} else if sugg.style == SuggestionStyle::HideCodeAlways {
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);
match sugg.style {
SuggestionStyle::CompletelyHidden => {
// do not display this suggestion, it is meant only for tools
}
} else if let Err(e) = self.emit_suggestion_default(
span,
sugg,
args,
&Level::Help,
max_line_num_len,
) {
panic!("failed to emit error: {}", e);
};
SuggestionStyle::HideCodeAlways => {
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);
}
}
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);
}
}
}
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_hir_analysis/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,10 +385,9 @@ pub fn check_generic_arg_count_for_call(
) -> GenericArgCountResult {
let empty_args = hir::GenericArgs::none();
let gen_args = seg.args.unwrap_or(&empty_args);
let gen_pos = if is_method_call == IsMethodCall::Yes {
GenericArgPosition::MethodCall
} else {
GenericArgPosition::Value
let gen_pos = match is_method_call {
IsMethodCall::Yes => GenericArgPosition::MethodCall,
IsMethodCall::No => GenericArgPosition::Value,
};
let has_self = generics.parent.is_none() && generics.has_self;

Expand Down
103 changes: 55 additions & 48 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,59 +605,66 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
};
check_abi(tcx, it.hir_id(), it.span, abi);

if abi == Abi::RustIntrinsic {
for item in items {
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);
match abi {
Abi::RustIntrinsic => {
for item in items {
let item = tcx.hir().foreign_item(item.id);
intrinsic::check_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();

Abi::PlatformIntrinsic => {
for item in items {
let item = tcx.hir().foreign_item(item.id);
intrinsic::check_platform_intrinsic_type(tcx, item);
}
}

let item = tcx.hir().foreign_item(item.id);
match &item.kind {
hir::ForeignItemKind::Fn(fn_decl, _, _) => {
require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span);
_ => {
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);
check_static_linkage(tcx, def_id);

let item = tcx.hir().foreign_item(item.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);
}
_ => {}
}
_ => {}
}
}
}
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ use rustc_ast_pretty::pp::{self, Breaks};
use rustc_ast_pretty::pprust::{Comments, PrintState};
use rustc_hir as hir;
use rustc_hir::LifetimeParamKind;
use rustc_hir::{
BindingAnnotation, ByRef, GenericArg, GenericParam, GenericParamKind, Mutability, Node, Term,
};
use rustc_hir::{BindingAnnotation, ByRef, GenericArg, GenericParam, GenericParamKind, Node, Term};
use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol};
Expand Down Expand Up @@ -1746,7 +1744,7 @@ impl<'a> State<'a> {
if by_ref == ByRef::Yes {
self.word_nbsp("ref");
}
if mutbl == Mutability::Mut {
if mutbl.is_mut() {
self.word_nbsp("mut");
}
self.print_ident(ident);
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1354,13 +1354,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
return Some(Err(MethodError::Ambiguity(sources)));
}

applicable_candidates.pop().map(|(probe, status)| {
if status == ProbeResult::Match {
applicable_candidates.pop().map(|(probe, status)| match status {
ProbeResult::Match => {
Ok(probe
.to_unadjusted_pick(self_ty, unstable_candidates.cloned().unwrap_or_default()))
} else {
Err(MethodError::BadReturnType)
}
ProbeResult::NoMatch | ProbeResult::BadReturnType => Err(MethodError::BadReturnType),
})
}
}
Expand Down
41 changes: 21 additions & 20 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,27 +580,28 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
}

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);
if context == MethodLateContext::TraitImpl {
return;
}

// If the method is an impl for an item with docs_hidden, don't doc.
if context == MethodLateContext::PlainImpl {
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id());
let impl_ty = cx.tcx.type_of(parent);
let outerdef = match impl_ty.kind() {
ty::Adt(def, _) => Some(def.did()),
ty::Foreign(def_id) => Some(*def_id),
_ => None,
};
let is_hidden = match outerdef {
Some(id) => cx.tcx.is_doc_hidden(id),
None => false,
};
if is_hidden {
return;

match context {
// If the method is an impl for a trait, don't doc.
MethodLateContext::TraitImpl => return,
MethodLateContext::TraitAutoImpl => {}
// If the method is an impl for an item with docs_hidden, don't doc.
MethodLateContext::PlainImpl => {
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id());
let impl_ty = cx.tcx.type_of(parent);
let outerdef = match impl_ty.kind() {
ty::Adt(def, _) => Some(def.did()),
ty::Foreign(def_id) => Some(*def_id),
_ => None,
};
let is_hidden = match outerdef {
Some(id) => cx.tcx.is_doc_hidden(id),
None => false,
};
if is_hidden {
return;
}
}
}

Expand Down
Loading