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

Check discriminant types before span_mirbug #100498

Closed
wants to merge 5 commits into from
Closed

Conversation

ouz-a
Copy link
Contributor

@ouz-a ouz-a commented Aug 13, 2022

The compiler is unable to relate types when a user tries to write a bound for std::ops::Index<usize>, and gives out an error, we bypass that by proving LHS and RHS are discriminantly the same types.

We now check if the expr is LangItem::Index while inside fix_index_builtin_expr if so we don't execute the function.

Mentored by @compiler-errors

The problem regarding the issue is explained greatly here by @danielhenrymantilla

Fixes #91633

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Aug 13, 2022
@rust-highfive
Copy link
Collaborator

r? @lcnr

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 13, 2022
@rust-log-analyzer

This comment has been minimized.

Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some nits and small changes. Functionality-wise I think this looks good.

});

if base_ty.builtin_index().is_some()
if self.is_builtin_index(&e, *base_ty, index_ty, base.span, index.span)
&& index_ty == self.fcx.tcx.types.usize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can move this into the is_builtin_index function too I think

fn is_builtin_index(
&mut self,
e: &hir::Expr<'_>,
base: Ty<'tcx>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit, not needed) maybe just me, but I prefer Ty<'tcx> variables to be called something_ty

base_span: Span,
index_span: Span,
) -> bool {
let mut ret = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this in favor of return true or return false where needed.

index_span: Span,
) -> bool {
let mut ret = false;
if (&base).builtin_index().is_some() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (&base).builtin_index().is_some() {
if base.builtin_index().is_some() {

Also, we could invert this, like:

if base.builtin_index().is_none() {
  return false;
}

That saves us an indentation level.

let resolved_base_ty = self.resolve(base, &base_span);
let resolved_index_ty = self.resolve(index, &index_span);
self.tcx().infer_ctxt().enter(|infcx| {
let mut selection_context = SelectionContext::new(&infcx);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think it's conventional to call the selection context selcx

self.tcx().infer_ctxt().enter(|infcx| {
let mut selection_context = SelectionContext::new(&infcx);

let def_id = self.tcx().require_lang_item(LangItem::Index, Some(e.span));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We could probably use a let else here, and just return false; if this lang item is missing rather than erroring.

Comment on lines +230 to +237
if let Ok(Some(ImplSource::Param(..))) = results {
ret = false;
} else {
ret = true;
}
});
}
ret
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if let Ok(Some(ImplSource::Param(..))) = results {
ret = false;
} else {
ret = true;
}
});
}
ret
// Due to coherence, the only `impl` that could apply is the built-in one
if let Ok(Some(ImplSource::UserDefined(..))) = results {
return true;
}
});
}
false

@ouz-a
Copy link
Contributor Author

ouz-a commented Aug 15, 2022

Going to close this down as it differs greatly from the original solution.

@ouz-a ouz-a closed this Aug 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ICE for broken MIR in 1.57.0, beta and nightly
6 participants