use let chains in mir, resolve, target

This commit is contained in:
Kivooeo 2025-07-26 06:22:20 +05:00
parent bae38bad78
commit b8eb046e6e
28 changed files with 415 additions and 448 deletions

View file

@ -997,12 +997,11 @@ fn promote_candidates<'tcx>(
for candidate in candidates.into_iter().rev() {
let Location { block, statement_index } = candidate.location;
if let StatementKind::Assign(box (place, _)) = &body[block].statements[statement_index].kind
&& let Some(local) = place.as_local()
{
if let Some(local) = place.as_local() {
if temps[local] == TempState::PromotedOut {
// Already promoted.
continue;
}
if temps[local] == TempState::PromotedOut {
// Already promoted.
continue;
}
}
@ -1066,11 +1065,11 @@ fn promote_candidates<'tcx>(
_ => true,
});
let terminator = block.terminator_mut();
if let TerminatorKind::Drop { place, target, .. } = &terminator.kind {
if let Some(index) = place.as_local() {
if promoted(index) {
terminator.kind = TerminatorKind::Goto { target: *target };
}
if let TerminatorKind::Drop { place, target, .. } = &terminator.kind
&& let Some(index) = place.as_local()
{
if promoted(index) {
terminator.kind = TerminatorKind::Goto { target: *target };
}
}
}

View file

@ -48,14 +48,13 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect();
for bb in postorder {
debug!(" processing {:?}", bb);
if let Some(unwind) = body[bb].terminator_mut().unwind_mut() {
if let UnwindAction::Cleanup(unwind_bb) = *unwind {
if nop_landing_pads.contains(unwind_bb) {
debug!(" removing noop landing pad");
landing_pads_removed += 1;
*unwind = UnwindAction::Continue;
}
}
if let Some(unwind) = body[bb].terminator_mut().unwind_mut()
&& let UnwindAction::Cleanup(unwind_bb) = *unwind
&& nop_landing_pads.contains(unwind_bb)
{
debug!(" removing noop landing pad");
landing_pads_removed += 1;
*unwind = UnwindAction::Continue;
}
body[bb].terminator_mut().successors_mut(|target| {

View file

@ -80,15 +80,14 @@ impl<'tcx> crate::MirPass<'tcx> for Validator {
cfg_checker.fail(location, msg);
}
if let MirPhase::Runtime(_) = body.phase {
if let ty::InstanceKind::Item(_) = body.source.instance {
if body.has_free_regions() {
cfg_checker.fail(
Location::START,
format!("Free regions in optimized {} MIR", body.phase.name()),
);
}
}
if let MirPhase::Runtime(_) = body.phase
&& let ty::InstanceKind::Item(_) = body.source.instance
&& body.has_free_regions()
{
cfg_checker.fail(
Location::START,
format!("Free regions in optimized {} MIR", body.phase.name()),
);
}
}

View file

@ -1178,12 +1178,11 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio
let autodiff_items = tcx.arena.alloc_from_iter(autodiff_items);
// Output monomorphization stats per def_id
if let SwitchWithOptPath::Enabled(ref path) = tcx.sess.opts.unstable_opts.dump_mono_stats {
if let Err(err) =
if let SwitchWithOptPath::Enabled(ref path) = tcx.sess.opts.unstable_opts.dump_mono_stats
&& let Err(err) =
dump_mono_items_stats(tcx, codegen_units, path, tcx.crate_name(LOCAL_CRATE))
{
tcx.dcx().emit_fatal(CouldntDumpMonoStats { error: err.to_string() });
}
{
tcx.dcx().emit_fatal(CouldntDumpMonoStats { error: err.to_string() });
}
if tcx.sess.opts.unstable_opts.print_mono_items {

View file

@ -1973,21 +1973,21 @@ impl<'a> Parser<'a> {
format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token));
// Try to recover extra trailing angle brackets
if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind {
if let Some(last_segment) = segments.last() {
let guar = self.check_trailing_angle_brackets(
last_segment,
&[exp!(Comma), exp!(CloseBrace)],
);
if let Some(_guar) = guar {
// Handle a case like `Vec<u8>>,` where we can continue parsing fields
// after the comma
let _ = self.eat(exp!(Comma));
if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
&& let Some(last_segment) = segments.last()
{
let guar = self.check_trailing_angle_brackets(
last_segment,
&[exp!(Comma), exp!(CloseBrace)],
);
if let Some(_guar) = guar {
// Handle a case like `Vec<u8>>,` where we can continue parsing fields
// after the comma
let _ = self.eat(exp!(Comma));
// `check_trailing_angle_brackets` already emitted a nicer error, as
// proven by the presence of `_guar`. We can continue parsing.
return Ok(a_var);
}
// `check_trailing_angle_brackets` already emitted a nicer error, as
// proven by the presence of `_guar`. We can continue parsing.
return Ok(a_var);
}
}
@ -3034,18 +3034,16 @@ impl<'a> Parser<'a> {
if let Ok(t) = &ty {
// Check for trailing angle brackets
if let TyKind::Path(_, Path { segments, .. }) = &t.kind {
if let Some(segment) = segments.last() {
if let Some(guar) =
this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
{
return Ok((
dummy_arg(segment.ident, guar),
Trailing::No,
UsePreAttrPos::No,
));
}
}
if let TyKind::Path(_, Path { segments, .. }) = &t.kind
&& let Some(segment) = segments.last()
&& let Some(guar) =
this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
{
return Ok((
dummy_arg(segment.ident, guar),
Trailing::No,
UsePreAttrPos::No,
));
}
if this.token != token::Comma && this.token != token::CloseParen {

View file

@ -104,10 +104,10 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
fn visit_inline_asm(&mut self, asm: &'tcx hir::InlineAsm<'tcx>, id: hir::HirId) {
for (op, _) in asm.operands {
if let hir::InlineAsmOperand::SymStatic { def_id, .. } = op {
if let Some(def_id) = def_id.as_local() {
self.reachable_symbols.insert(def_id);
}
if let hir::InlineAsmOperand::SymStatic { def_id, .. } = op
&& let Some(def_id) = def_id.as_local()
{
self.reachable_symbols.insert(def_id);
}
}
intravisit::walk_inline_asm(self, asm, id);

View file

@ -929,10 +929,10 @@ struct CheckTraitImplStable<'tcx> {
impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
fn visit_path(&mut self, path: &hir::Path<'tcx>, _id: hir::HirId) {
if let Some(def_id) = path.res.opt_def_id() {
if let Some(stab) = self.tcx.lookup_stability(def_id) {
self.fully_stable &= stab.level.is_stable();
}
if let Some(def_id) = path.res.opt_def_id()
&& let Some(stab) = self.tcx.lookup_stability(def_id)
{
self.fully_stable &= stab.level.is_stable();
}
intravisit::walk_path(self, path)
}
@ -1055,10 +1055,10 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
// implications from this crate.
remaining_implications.remove(&feature);
if let FeatureStability::Unstable { old_name: Some(alias) } = stability {
if let Some(span) = remaining_lib_features.swap_remove(&alias) {
tcx.dcx().emit_err(errors::RenamedFeature { span, feature, alias });
}
if let FeatureStability::Unstable { old_name: Some(alias) } = stability
&& let Some(span) = remaining_lib_features.swap_remove(&alias)
{
tcx.dcx().emit_err(errors::RenamedFeature { span, feature, alias });
}
if remaining_lib_features.is_empty() && remaining_implications.is_empty() {

View file

@ -75,19 +75,19 @@ impl<'tcx> Visitor<'tcx> for CaptureCollector<'_, 'tcx> {
}
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
if let hir::ExprKind::Closure(closure) = expr.kind {
if let Some(upvars) = self.tcx.upvars_mentioned(closure.def_id) {
// Every capture of a closure expression is a local in scope,
// that is moved/copied/borrowed into the closure value, and
// for this analysis they are like any other access to a local.
//
// E.g. in `|b| |c| (a, b, c)`, the upvars of the inner closure
// are `a` and `b`, and while `a` is not directly used in the
// outer closure, it needs to be an upvar there too, so that
// the inner closure can take it (from the outer closure's env).
for (&var_id, upvar) in upvars {
self.visit_local_use(var_id, upvar.span);
}
if let hir::ExprKind::Closure(closure) = expr.kind
&& let Some(upvars) = self.tcx.upvars_mentioned(closure.def_id)
{
// Every capture of a closure expression is a local in scope,
// that is moved/copied/borrowed into the closure value, and
// for this analysis they are like any other access to a local.
//
// E.g. in `|b| |c| (a, b, c)`, the upvars of the inner closure
// are `a` and `b`, and while `a` is not directly used in the
// outer closure, it needs to be an upvar there too, so that
// the inner closure can take it (from the outer closure's env).
for (&var_id, upvar) in upvars {
self.visit_local_use(var_id, upvar.span);
}
}

View file

@ -204,12 +204,10 @@ where
// Something like `fn() {my_method}` type of the method
// `impl Pub<Priv> { pub fn my_method() {} }` is considered a private type,
// so we need to visit the self type additionally.
if let Some(assoc_item) = tcx.opt_associated_item(def_id) {
if let Some(impl_def_id) = assoc_item.impl_container(tcx) {
try_visit!(
tcx.type_of(impl_def_id).instantiate_identity().visit_with(self)
);
}
if let Some(assoc_item) = tcx.opt_associated_item(def_id)
&& let Some(impl_def_id) = assoc_item.impl_container(tcx)
{
try_visit!(tcx.type_of(impl_def_id).instantiate_identity().visit_with(self));
}
}
ty::Alias(kind @ (ty::Inherent | ty::Free | ty::Projection), data) => {
@ -734,6 +732,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
if let Some(ctor_def_id) = variant.data.ctor_def_id() {
self.update(ctor_def_id, variant_ev, Level::Reachable);
}
for field in variant.data.fields() {
self.update(field.def_id, variant_ev, Level::Reachable);
self.reach(field.def_id, variant_ev).ty();

View file

@ -498,12 +498,12 @@ impl<D: Deps> DepGraph<D> {
#[cfg(debug_assertions)]
{
if let Some(target) = task_deps.node {
if let Some(ref forbidden_edge) = data.current.forbidden_edge {
let src = forbidden_edge.index_to_node.lock()[&dep_node_index];
if forbidden_edge.test(&src, &target) {
panic!("forbidden edge {:?} -> {:?} created", src, target)
}
if let Some(target) = task_deps.node
&& let Some(ref forbidden_edge) = data.current.forbidden_edge
{
let src = forbidden_edge.index_to_node.lock()[&dep_node_index];
if forbidden_edge.test(&src, &target) {
panic!("forbidden edge {:?} -> {:?} created", src, target)
}
}
}

View file

@ -289,10 +289,10 @@ where
F: FnMut(Span, QueryJobId) -> Option<Option<Waiter>>,
{
// Visit the parent query which is a non-resumable waiter since it's on the same stack
if let Some(parent) = query.parent(query_map) {
if let Some(cycle) = visit(query.span(query_map), parent) {
return Some(cycle);
}
if let Some(parent) = query.parent(query_map)
&& let Some(cycle) = visit(query.span(query_map), parent)
{
return Some(cycle);
}
// Visit the explicit waiters which use condvars and are resumable

View file

@ -818,10 +818,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
// If the first argument in call is `self` suggest calling a method.
if let Some((call_span, args_span)) = self.call_has_self_arg(source) {
let mut args_snippet = String::new();
if let Some(args_span) = args_span {
if let Ok(snippet) = self.r.tcx.sess.source_map().span_to_snippet(args_span) {
args_snippet = snippet;
}
if let Some(args_span) = args_span
&& let Ok(snippet) = self.r.tcx.sess.source_map().span_to_snippet(args_span)
{
args_snippet = snippet;
}
err.span_suggestion(
@ -955,59 +955,57 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)),
false,
) = (source, res, is_macro)
{
if let Some(bounds @ [first_bound, .., last_bound]) =
&& let Some(bounds @ [first_bound, .., last_bound]) =
self.diag_metadata.current_trait_object
{
fallback = true;
let spans: Vec<Span> = bounds
.iter()
.map(|bound| bound.span())
.filter(|&sp| sp != base_error.span)
.collect();
{
fallback = true;
let spans: Vec<Span> = bounds
.iter()
.map(|bound| bound.span())
.filter(|&sp| sp != base_error.span)
.collect();
let start_span = first_bound.span();
// `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><)
let end_span = last_bound.span();
// `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar)
let last_bound_span = spans.last().cloned().unwrap();
let mut multi_span: MultiSpan = spans.clone().into();
for sp in spans {
let msg = if sp == last_bound_span {
format!(
"...because of {these} bound{s}",
these = pluralize!("this", bounds.len() - 1),
s = pluralize!(bounds.len() - 1),
)
} else {
String::new()
};
multi_span.push_span_label(sp, msg);
}
multi_span.push_span_label(base_error.span, "expected this type to be a trait...");
err.span_help(
multi_span,
"`+` is used to constrain a \"trait object\" type with lifetimes or \
let start_span = first_bound.span();
// `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><)
let end_span = last_bound.span();
// `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar)
let last_bound_span = spans.last().cloned().unwrap();
let mut multi_span: MultiSpan = spans.clone().into();
for sp in spans {
let msg = if sp == last_bound_span {
format!(
"...because of {these} bound{s}",
these = pluralize!("this", bounds.len() - 1),
s = pluralize!(bounds.len() - 1),
)
} else {
String::new()
};
multi_span.push_span_label(sp, msg);
}
multi_span.push_span_label(base_error.span, "expected this type to be a trait...");
err.span_help(
multi_span,
"`+` is used to constrain a \"trait object\" type with lifetimes or \
auto-traits; structs and enums can't be bound in that way",
);
if bounds.iter().all(|bound| match bound {
ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true,
ast::GenericBound::Trait(tr) => tr.span == base_error.span,
}) {
let mut sugg = vec![];
if base_error.span != start_span {
sugg.push((start_span.until(base_error.span), String::new()));
}
if base_error.span != end_span {
sugg.push((base_error.span.shrink_to_hi().to(end_span), String::new()));
}
err.multipart_suggestion(
"if you meant to use a type and not a trait here, remove the bounds",
sugg,
Applicability::MaybeIncorrect,
);
);
if bounds.iter().all(|bound| match bound {
ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true,
ast::GenericBound::Trait(tr) => tr.span == base_error.span,
}) {
let mut sugg = vec![];
if base_error.span != start_span {
sugg.push((start_span.until(base_error.span), String::new()));
}
if base_error.span != end_span {
sugg.push((base_error.span.shrink_to_hi().to(end_span), String::new()));
}
err.multipart_suggestion(
"if you meant to use a type and not a trait here, remove the bounds",
sugg,
Applicability::MaybeIncorrect,
);
}
}
@ -1151,13 +1149,13 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
}
err.code(E0411);
err.span_label(span, "`Self` is only available in impls, traits, and type definitions");
if let Some(item) = self.diag_metadata.current_item {
if let Some(ident) = item.kind.ident() {
err.span_label(
ident.span,
format!("`Self` not allowed in {} {}", item.kind.article(), item.kind.descr()),
);
}
if let Some(item) = self.diag_metadata.current_item
&& let Some(ident) = item.kind.ident()
{
err.span_label(
ident.span,
format!("`Self` not allowed in {} {}", item.kind.article(), item.kind.descr()),
);
}
true
}
@ -1932,11 +1930,11 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
};
let (ctor_def, ctor_vis, fields) = if let Some(struct_ctor) = struct_ctor {
if let PathSource::Expr(Some(parent)) = source {
if let ExprKind::Field(..) | ExprKind::MethodCall(..) = parent.kind {
bad_struct_syntax_suggestion(self, err, def_id);
return true;
}
if let PathSource::Expr(Some(parent)) = source
&& let ExprKind::Field(..) | ExprKind::MethodCall(..) = parent.kind
{
bad_struct_syntax_suggestion(self, err, def_id);
return true;
}
struct_ctor
} else {
@ -2344,19 +2342,13 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
if filter_fn(Res::Local(ast::DUMMY_NODE_ID)) {
if let Some(node_id) =
self.diag_metadata.current_self_type.as_ref().and_then(extract_node_id)
&& let Some(resolution) = self.r.partial_res_map.get(&node_id)
&& let Some(Res::Def(DefKind::Struct | DefKind::Union, did)) = resolution.full_res()
&& let Some(fields) = self.r.field_idents(did)
&& let Some(field) = fields.iter().find(|id| ident.name == id.name)
{
// Look for a field with the same name in the current self_type.
if let Some(resolution) = self.r.partial_res_map.get(&node_id) {
if let Some(Res::Def(DefKind::Struct | DefKind::Union, did)) =
resolution.full_res()
{
if let Some(fields) = self.r.field_idents(did) {
if let Some(field) = fields.iter().find(|id| ident.name == id.name) {
return Some(AssocSuggestion::Field(field.span));
}
}
}
}
return Some(AssocSuggestion::Field(field.span));
}
}
@ -2391,44 +2383,44 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
}
// Look for associated items in the current trait.
if let Some((module, _)) = self.current_trait_ref {
if let Ok(binding) = self.r.maybe_resolve_ident_in_module(
if let Some((module, _)) = self.current_trait_ref
&& let Ok(binding) = self.r.maybe_resolve_ident_in_module(
ModuleOrUniformRoot::Module(module),
ident,
ns,
&self.parent_scope,
None,
) {
let res = binding.res();
if filter_fn(res) {
match res {
Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => {
let has_self = match def_id.as_local() {
Some(def_id) => self
.r
.delegation_fn_sigs
.get(&def_id)
.is_some_and(|sig| sig.has_self),
None => {
self.r.tcx.fn_arg_idents(def_id).first().is_some_and(|&ident| {
matches!(ident, Some(Ident { name: kw::SelfLower, .. }))
})
}
};
if has_self {
return Some(AssocSuggestion::MethodWithSelf { called });
} else {
return Some(AssocSuggestion::AssocFn { called });
)
{
let res = binding.res();
if filter_fn(res) {
match res {
Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => {
let has_self = match def_id.as_local() {
Some(def_id) => self
.r
.delegation_fn_sigs
.get(&def_id)
.is_some_and(|sig| sig.has_self),
None => {
self.r.tcx.fn_arg_idents(def_id).first().is_some_and(|&ident| {
matches!(ident, Some(Ident { name: kw::SelfLower, .. }))
})
}
};
if has_self {
return Some(AssocSuggestion::MethodWithSelf { called });
} else {
return Some(AssocSuggestion::AssocFn { called });
}
Res::Def(DefKind::AssocConst, _) => {
return Some(AssocSuggestion::AssocConst);
}
Res::Def(DefKind::AssocTy, _) => {
return Some(AssocSuggestion::AssocType);
}
_ => {}
}
Res::Def(DefKind::AssocConst, _) => {
return Some(AssocSuggestion::AssocConst);
}
Res::Def(DefKind::AssocTy, _) => {
return Some(AssocSuggestion::AssocType);
}
_ => {}
}
}
}

View file

@ -1023,40 +1023,39 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
node_id: NodeId,
) {
let span = path.span;
if let Some(stability) = &ext.stability {
if let StabilityLevel::Unstable { reason, issue, is_soft, implied_by, .. } =
if let Some(stability) = &ext.stability
&& let StabilityLevel::Unstable { reason, issue, is_soft, implied_by, .. } =
stability.level
{
let feature = stability.feature;
{
let feature = stability.feature;
let is_allowed =
|feature| self.tcx.features().enabled(feature) || span.allows_unstable(feature);
let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
if !is_allowed(feature) && !allowed_by_implication {
let lint_buffer = &mut self.lint_buffer;
let soft_handler = |lint, span, msg: String| {
lint_buffer.buffer_lint(
lint,
node_id,
span,
BuiltinLintDiag::UnstableFeature(
// FIXME make this translatable
msg.into(),
),
)
};
stability::report_unstable(
self.tcx.sess,
feature,
reason.to_opt_reason(),
issue,
None,
is_soft,
let is_allowed =
|feature| self.tcx.features().enabled(feature) || span.allows_unstable(feature);
let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
if !is_allowed(feature) && !allowed_by_implication {
let lint_buffer = &mut self.lint_buffer;
let soft_handler = |lint, span, msg: String| {
lint_buffer.buffer_lint(
lint,
node_id,
span,
soft_handler,
stability::UnstableKind::Regular,
);
}
BuiltinLintDiag::UnstableFeature(
// FIXME make this translatable
msg.into(),
),
)
};
stability::report_unstable(
self.tcx.sess,
feature,
reason.to_opt_reason(),
issue,
None,
is_soft,
span,
soft_handler,
stability::UnstableKind::Regular,
);
}
}
if let Some(depr) = &ext.deprecation {

View file

@ -107,10 +107,10 @@ pub fn feature_err_issue(
let span = span.into();
// Cancel an earlier warning for this same error, if it exists.
if let Some(span) = span.primary_span() {
if let Some(err) = sess.dcx().steal_non_err(span, StashKey::EarlySyntaxWarning) {
err.cancel()
}
if let Some(span) = span.primary_span()
&& let Some(err) = sess.dcx().steal_non_err(span, StashKey::EarlySyntaxWarning)
{
err.cancel()
}
let mut err = sess.dcx().create_err(FeatureGateError { span, explain: explain.into() });

View file

@ -1362,11 +1362,11 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
sess.dcx().emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() });
}
if let Some(flavor) = sess.opts.cg.linker_flavor {
if let Some(compatible_list) = sess.target.linker_flavor.check_compatibility(flavor) {
let flavor = flavor.desc();
sess.dcx().emit_err(errors::IncompatibleLinkerFlavor { flavor, compatible_list });
}
if let Some(flavor) = sess.opts.cg.linker_flavor
&& let Some(compatible_list) = sess.target.linker_flavor.check_compatibility(flavor)
{
let flavor = flavor.desc();
sess.dcx().emit_err(errors::IncompatibleLinkerFlavor { flavor, compatible_list });
}
if sess.opts.unstable_opts.function_return != FunctionReturn::default() {

View file

@ -826,10 +826,10 @@ impl SourceMap {
/// Given a `Span`, tries to get a shorter span ending just after the first occurrence of `char`
/// `c`.
pub fn span_through_char(&self, sp: Span, c: char) -> Span {
if let Ok(snippet) = self.span_to_snippet(sp) {
if let Some(offset) = snippet.find(c) {
return sp.with_hi(BytePos(sp.lo().0 + (offset + c.len_utf8()) as u32));
}
if let Ok(snippet) = self.span_to_snippet(sp)
&& let Some(offset) = snippet.find(c)
{
return sp.with_hi(BytePos(sp.lo().0 + (offset + c.len_utf8()) as u32));
}
sp
}

View file

@ -314,16 +314,15 @@ fn classify_arg<'a, Ty, C>(
}
fn extend_integer_width<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64) {
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
if let Primitive::Int(i, _) = scalar.primitive() {
// 32-bit integers are always sign-extended
if i.size().bits() == 32 && xlen > 32 {
if let PassMode::Direct(ref mut attrs) = arg.mode {
attrs.ext(ArgExtension::Sext);
return;
}
}
}
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr
&& let Primitive::Int(i, _) = scalar.primitive()
&& i.size().bits() == 32
&& xlen > 32
&& let PassMode::Direct(ref mut attrs) = arg.mode
{
// 32-bit integers are always sign-extended
attrs.ext(ArgExtension::Sext);
return;
}
arg.extend_integer_width_to(xlen);

View file

@ -6,15 +6,14 @@ use crate::callconv::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform
fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
// Always sign extend u32 values on 64-bit mips
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
if let Primitive::Int(i, signed) = scalar.primitive() {
if !signed && i.size().bits() == 32 {
if let PassMode::Direct(ref mut attrs) = arg.mode {
attrs.ext(ArgExtension::Sext);
return;
}
}
}
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr
&& let Primitive::Int(i, signed) = scalar.primitive()
&& !signed
&& i.size().bits() == 32
&& let PassMode::Direct(ref mut attrs) = arg.mode
{
attrs.ext(ArgExtension::Sext);
return;
}
arg.extend_integer_width_to(bits);
@ -58,13 +57,12 @@ where
ret.cast_to(reg);
return;
}
} else if ret.layout.fields.count() == 2 {
if let Some(reg0) = float_reg(cx, ret, 0) {
if let Some(reg1) = float_reg(cx, ret, 1) {
ret.cast_to(CastTarget::pair(reg0, reg1));
return;
}
}
} else if ret.layout.fields.count() == 2
&& let Some(reg0) = float_reg(cx, ret, 0)
&& let Some(reg1) = float_reg(cx, ret, 1)
{
ret.cast_to(CastTarget::pair(reg0, reg1));
return;
}
}

View file

@ -495,18 +495,16 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
pub fn extend_integer_width_to(&mut self, bits: u64) {
// Only integers have signedness
if let BackendRepr::Scalar(scalar) = self.layout.backend_repr {
if let Primitive::Int(i, signed) = scalar.primitive() {
if i.size().bits() < bits {
if let PassMode::Direct(ref mut attrs) = self.mode {
if signed {
attrs.ext(ArgExtension::Sext)
} else {
attrs.ext(ArgExtension::Zext)
};
}
}
}
if let BackendRepr::Scalar(scalar) = self.layout.backend_repr
&& let Primitive::Int(i, signed) = scalar.primitive()
&& i.size().bits() < bits
&& let PassMode::Direct(ref mut attrs) = self.mode
{
if signed {
attrs.ext(ArgExtension::Sext)
} else {
attrs.ext(ArgExtension::Zext)
};
}
}

View file

@ -393,16 +393,14 @@ fn classify_arg<'a, Ty, C>(
}
fn extend_integer_width<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64) {
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
if let Primitive::Int(i, _) = scalar.primitive() {
// 32-bit integers are always sign-extended
if i.size().bits() == 32 && xlen > 32 {
if let PassMode::Direct(ref mut attrs) = arg.mode {
attrs.ext(ArgExtension::Sext);
return;
}
}
}
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr
&& let Primitive::Int(i, _) = scalar.primitive()
&& i.size().bits() == 32
&& xlen > 32
&& let PassMode::Direct(ref mut attrs) = arg.mode
{
attrs.ext(ArgExtension::Sext);
return;
}
arg.extend_integer_width_to(xlen);

View file

@ -104,10 +104,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
ty::AssocKind::Fn { .. } => {
if let Some(hir_id) =
assoc_item.def_id.as_local().map(|id| self.tcx().local_def_id_to_hir_id(id))
&& let Some(decl) = self.tcx().hir_fn_decl_by_hir_id(hir_id)
{
if let Some(decl) = self.tcx().hir_fn_decl_by_hir_id(hir_id) {
visitor.visit_fn_decl(decl);
}
visitor.visit_fn_decl(decl);
}
}
_ => {}

View file

@ -91,51 +91,51 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
) {
// Heavily inspired by `FnCtxt::suggest_compatible_variants`, with
// some modifications due to that being in typeck and this being in infer.
if let ObligationCauseCode::Pattern { .. } = cause.code() {
if let ty::Adt(expected_adt, args) = exp_found.expected.kind() {
let compatible_variants: Vec<_> = expected_adt
.variants()
.iter()
.filter(|variant| {
variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn)
})
.filter_map(|variant| {
let sole_field = &variant.single_field();
let sole_field_ty = sole_field.ty(self.tcx, args);
if self.same_type_modulo_infer(sole_field_ty, exp_found.found) {
let variant_path =
with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
// FIXME #56861: DRYer prelude filtering
if let Some(path) = variant_path.strip_prefix("std::prelude::") {
if let Some((_, path)) = path.split_once("::") {
return Some(path.to_string());
}
}
Some(variant_path)
} else {
None
if let ObligationCauseCode::Pattern { .. } = cause.code()
&& let ty::Adt(expected_adt, args) = exp_found.expected.kind()
{
let compatible_variants: Vec<_> = expected_adt
.variants()
.iter()
.filter(|variant| {
variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn)
})
.filter_map(|variant| {
let sole_field = &variant.single_field();
let sole_field_ty = sole_field.ty(self.tcx, args);
if self.same_type_modulo_infer(sole_field_ty, exp_found.found) {
let variant_path =
with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
// FIXME #56861: DRYer prelude filtering
if let Some(path) = variant_path.strip_prefix("std::prelude::")
&& let Some((_, path)) = path.split_once("::")
{
return Some(path.to_string());
}
})
.collect();
match &compatible_variants[..] {
[] => {}
[variant] => {
let sugg = SuggestTuplePatternOne {
variant: variant.to_owned(),
span_low: cause.span.shrink_to_lo(),
span_high: cause.span.shrink_to_hi(),
};
diag.subdiagnostic(sugg);
}
_ => {
// More than one matching variant.
let sugg = SuggestTuplePatternMany {
path: self.tcx.def_path_str(expected_adt.did()),
cause_span: cause.span,
compatible_variants,
};
diag.subdiagnostic(sugg);
Some(variant_path)
} else {
None
}
})
.collect();
match &compatible_variants[..] {
[] => {}
[variant] => {
let sugg = SuggestTuplePatternOne {
variant: variant.to_owned(),
span_low: cause.span.shrink_to_lo(),
span_high: cause.span.shrink_to_hi(),
};
diag.subdiagnostic(sugg);
}
_ => {
// More than one matching variant.
let sugg = SuggestTuplePatternMany {
path: self.tcx.def_path_str(expected_adt.did()),
cause_span: cause.span,
compatible_variants,
};
diag.subdiagnostic(sugg);
}
}
}
@ -288,19 +288,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
.filter(|field| field.vis.is_accessible_from(field.did, self.tcx))
.map(|field| (field.name, field.ty(self.tcx, expected_args)))
.find(|(_, ty)| self.same_type_modulo_infer(*ty, exp_found.found))
&& let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code()
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
{
if let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code() {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
let suggestion = if expected_def.is_struct() {
SuggestAccessingField::Safe { span, snippet, name, ty }
} else if expected_def.is_union() {
SuggestAccessingField::Unsafe { span, snippet, name, ty }
} else {
return;
};
diag.subdiagnostic(suggestion);
}
}
let suggestion = if expected_def.is_struct() {
SuggestAccessingField::Safe { span, snippet, name, ty }
} else if expected_def.is_union() {
SuggestAccessingField::Unsafe { span, snippet, name, ty }
} else {
return;
};
diag.subdiagnostic(suggestion);
}
}
}
@ -540,38 +538,35 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
) -> Option<SuggestAsRefKind> {
if let (ty::Adt(exp_def, exp_args), ty::Ref(_, found_ty, _)) =
(expected.kind(), found.kind())
&& let ty::Adt(found_def, found_args) = *found_ty.kind()
{
if let ty::Adt(found_def, found_args) = *found_ty.kind() {
if exp_def == &found_def {
let have_as_ref = &[
(sym::Option, SuggestAsRefKind::Option),
(sym::Result, SuggestAsRefKind::Result),
];
if let Some(msg) = have_as_ref.iter().find_map(|(name, msg)| {
self.tcx.is_diagnostic_item(*name, exp_def.did()).then_some(msg)
}) {
let mut show_suggestion = true;
for (exp_ty, found_ty) in
std::iter::zip(exp_args.types(), found_args.types())
{
match *exp_ty.kind() {
ty::Ref(_, exp_ty, _) => {
match (exp_ty.kind(), found_ty.kind()) {
(_, ty::Param(_))
| (_, ty::Infer(_))
| (ty::Param(_), _)
| (ty::Infer(_), _) => {}
_ if self.same_type_modulo_infer(exp_ty, found_ty) => {}
_ => show_suggestion = false,
};
}
ty::Param(_) | ty::Infer(_) => {}
_ => show_suggestion = false,
if exp_def == &found_def {
let have_as_ref = &[
(sym::Option, SuggestAsRefKind::Option),
(sym::Result, SuggestAsRefKind::Result),
];
if let Some(msg) = have_as_ref.iter().find_map(|(name, msg)| {
self.tcx.is_diagnostic_item(*name, exp_def.did()).then_some(msg)
}) {
let mut show_suggestion = true;
for (exp_ty, found_ty) in std::iter::zip(exp_args.types(), found_args.types()) {
match *exp_ty.kind() {
ty::Ref(_, exp_ty, _) => {
match (exp_ty.kind(), found_ty.kind()) {
(_, ty::Param(_))
| (_, ty::Infer(_))
| (ty::Param(_), _)
| (ty::Infer(_), _) => {}
_ if self.same_type_modulo_infer(exp_ty, found_ty) => {}
_ => show_suggestion = false,
};
}
ty::Param(_) | ty::Infer(_) => {}
_ => show_suggestion = false,
}
if show_suggestion {
return Some(*msg);
}
}
if show_suggestion {
return Some(*msg);
}
}
}

View file

@ -381,15 +381,15 @@ impl IgnoredDiagnosticOption {
old: Option<Span>,
option_name: &'static str,
) {
if let (Some(new_item), Some(old_item)) = (new, old) {
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
new_item,
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
);
}
if let (Some(new_item), Some(old_item)) = (new, old)
&& let Some(item_def_id) = item_def_id.as_local()
{
tcx.emit_node_span_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
new_item,
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
);
}
}
}

View file

@ -2213,26 +2213,26 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
span: Span,
trait_ref: DefId,
) {
if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id) {
if let ty::AssocKind::Const { .. } | ty::AssocKind::Type { .. } = assoc_item.kind {
err.note(format!(
"{}s cannot be accessed directly on a `trait`, they can only be \
if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id)
&& let ty::AssocKind::Const { .. } | ty::AssocKind::Type { .. } = assoc_item.kind
{
err.note(format!(
"{}s cannot be accessed directly on a `trait`, they can only be \
accessed through a specific `impl`",
self.tcx.def_kind_descr(assoc_item.as_def_kind(), item_def_id)
));
self.tcx.def_kind_descr(assoc_item.as_def_kind(), item_def_id)
));
if !assoc_item.is_impl_trait_in_trait() {
err.span_suggestion_verbose(
span,
"use the fully qualified path to an implementation",
format!(
"<Type as {}>::{}",
self.tcx.def_path_str(trait_ref),
assoc_item.name()
),
Applicability::HasPlaceholders,
);
}
if !assoc_item.is_impl_trait_in_trait() {
err.span_suggestion_verbose(
span,
"use the fully qualified path to an implementation",
format!(
"<Type as {}>::{}",
self.tcx.def_path_str(trait_ref),
assoc_item.name()
),
Applicability::HasPlaceholders,
);
}
}
}

View file

@ -695,15 +695,14 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
source: CandidateSource::Impl(def_id),
result: Ok(_),
} = cand.kind()
&& let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id)
{
if let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id) {
let message = infcx
.tcx
.get_attr(def_id, sym::rustc_reservation_impl)
.and_then(|a| a.value_str());
if let Some(message) = message {
self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message });
}
let message = infcx
.tcx
.get_attr(def_id, sym::rustc_reservation_impl)
.and_then(|a| a.value_str());
if let Some(message) = message {
self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message });
}
}
}

View file

@ -781,16 +781,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self,
&project_obligation,
)
{
if let Some(cached_res) = self
&& let Some(cached_res) = self
.infcx
.inner
.borrow_mut()
.projection_cache()
.is_complete(key)
{
break 'compute_res Ok(cached_res);
}
{
break 'compute_res Ok(cached_res);
}
// Need to explicitly set the depth of nested goals here as
@ -1436,24 +1434,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
let tcx = self.tcx();
// Treat reservation impls as ambiguity.
if let ImplCandidate(def_id) = candidate {
if let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) {
if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
let message = tcx
.get_attr(def_id, sym::rustc_reservation_impl)
.and_then(|a| a.value_str());
if let Some(message) = message {
debug!(
"filter_reservation_impls: \
if let ImplCandidate(def_id) = candidate
&& let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id)
{
if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
let message =
tcx.get_attr(def_id, sym::rustc_reservation_impl).and_then(|a| a.value_str());
if let Some(message) = message {
debug!(
"filter_reservation_impls: \
reservation impl ambiguity on {:?}",
def_id
);
intercrate_ambiguity_clauses
.insert(IntercrateAmbiguityCause::ReservationImpl { message });
}
def_id
);
intercrate_ambiguity_clauses
.insert(IntercrateAmbiguityCause::ReservationImpl { message });
}
return Ok(None);
}
return Ok(None);
}
Ok(Some(candidate))
}

View file

@ -642,11 +642,11 @@ fn fn_abi_adjust_for_abi<'tcx>(
// The `deduced_param_attrs` list could be empty if this is a type of function
// we can't deduce any parameters for, so make sure the argument index is in
// bounds.
if let Some(deduced_param_attrs) = deduced_param_attrs.get(arg_idx) {
if deduced_param_attrs.read_only {
attrs.regular.insert(ArgAttribute::ReadOnly);
debug!("added deduced read-only attribute");
}
if let Some(deduced_param_attrs) = deduced_param_attrs.get(arg_idx)
&& deduced_param_attrs.read_only
{
attrs.regular.insert(ArgAttribute::ReadOnly);
debug!("added deduced read-only attribute");
}
}
}

View file

@ -106,10 +106,10 @@ fn adt_sizedness_constraint<'tcx>(
tcx: TyCtxt<'tcx>,
(def_id, sizedness): (DefId, SizedTraitKind),
) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> {
if let Some(def_id) = def_id.as_local() {
if let ty::Representability::Infinite(_) = tcx.representability(def_id) {
return None;
}
if let Some(def_id) = def_id.as_local()
&& let ty::Representability::Infinite(_) = tcx.representability(def_id)
{
return None;
}
let def = tcx.adt_def(def_id);