-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -9,8 +9,10 @@ use rustc_data_structures::fx::FxHashMap; | |||||||||||||||||||||||||||||||
use rustc_errors::ErrorGuaranteed; | ||||||||||||||||||||||||||||||||
use rustc_hir as hir; | ||||||||||||||||||||||||||||||||
use rustc_hir::intravisit::{self, Visitor}; | ||||||||||||||||||||||||||||||||
use rustc_hir::lang_items::LangItem; | ||||||||||||||||||||||||||||||||
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; | ||||||||||||||||||||||||||||||||
use rustc_infer::infer::InferCtxt; | ||||||||||||||||||||||||||||||||
use rustc_infer::infer::TyCtxtInferExt; | ||||||||||||||||||||||||||||||||
use rustc_middle::hir::place::Place as HirPlace; | ||||||||||||||||||||||||||||||||
use rustc_middle::mir::FakeReadCause; | ||||||||||||||||||||||||||||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; | ||||||||||||||||||||||||||||||||
|
@@ -19,6 +21,7 @@ use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable}; | |||||||||||||||||||||||||||||||
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt}; | ||||||||||||||||||||||||||||||||
use rustc_span::symbol::sym; | ||||||||||||||||||||||||||||||||
use rustc_span::Span; | ||||||||||||||||||||||||||||||||
use rustc_trait_selection::traits::{self, ImplSource, SelectionContext}; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
use std::mem; | ||||||||||||||||||||||||||||||||
use std::ops::ControlFlow; | ||||||||||||||||||||||||||||||||
|
@@ -192,6 +195,48 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { | |||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// (ouz-a #100498): Normally `[T] : std::ops::Index<usize>` should be normalized | ||||||||||||||||||||||||||||||||
// into [T] but currently `Where` clause stops the normalization process for it, | ||||||||||||||||||||||||||||||||
// here we check if the expr is `LangItem::Index` and index_ty is `usize` if so we don't | ||||||||||||||||||||||||||||||||
// `fix_index_builtin_expr`. | ||||||||||||||||||||||||||||||||
fn is_builtin_index( | ||||||||||||||||||||||||||||||||
&mut self, | ||||||||||||||||||||||||||||||||
e: &hir::Expr<'_>, | ||||||||||||||||||||||||||||||||
base: Ty<'tcx>, | ||||||||||||||||||||||||||||||||
index: Ty<'tcx>, | ||||||||||||||||||||||||||||||||
base_span: Span, | ||||||||||||||||||||||||||||||||
index_span: Span, | ||||||||||||||||||||||||||||||||
) -> bool { | ||||||||||||||||||||||||||||||||
let mut ret = false; | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this in favor of |
||||||||||||||||||||||||||||||||
if (&base).builtin_index().is_some() { | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Also, we could invert this, like:
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); | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I think it's conventional to call the selection context |
||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
let def_id = self.tcx().require_lang_item(LangItem::Index, Some(e.span)); | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: We could probably use a |
||||||||||||||||||||||||||||||||
let substs = self | ||||||||||||||||||||||||||||||||
.tcx() | ||||||||||||||||||||||||||||||||
.mk_substs([resolved_base_ty.into(), resolved_index_ty.into()].iter()); | ||||||||||||||||||||||||||||||||
let trait_ref = ty::TraitRef { def_id, substs }; | ||||||||||||||||||||||||||||||||
let binder = ty::Binder::dummy(trait_ref).without_const(); | ||||||||||||||||||||||||||||||||
let obligation = traits::Obligation::new( | ||||||||||||||||||||||||||||||||
traits::ObligationCause::dummy_with_span(e.span), | ||||||||||||||||||||||||||||||||
self.fcx.param_env, | ||||||||||||||||||||||||||||||||
binder, | ||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||
let results = selection_context.select(&obligation); | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
if let Ok(Some(ImplSource::Param(..))) = results { | ||||||||||||||||||||||||||||||||
ret = false; | ||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||
ret = true; | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
ret | ||||||||||||||||||||||||||||||||
Comment on lines
+230
to
+237
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// Similar to operators, indexing is always assumed to be overloaded | ||||||||||||||||||||||||||||||||
// Here, correct cases where an indexing expression can be simplified | ||||||||||||||||||||||||||||||||
// to use builtin indexing because the index type is known to be | ||||||||||||||||||||||||||||||||
|
@@ -223,7 +268,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { | |||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||
let index_ty = self.fcx.resolve_vars_if_possible(index_ty); | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
if base_ty.builtin_index().is_some() && index_ty == self.fcx.tcx.types.usize { | ||||||||||||||||||||||||||||||||
if self.is_builtin_index(&e, *base_ty, index_ty, base.span, index.span) | ||||||||||||||||||||||||||||||||
&& index_ty == self.fcx.tcx.types.usize | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can move this into the |
||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||
// Remove the method call record | ||||||||||||||||||||||||||||||||
typeck_results.type_dependent_defs_mut().remove(e.hir_id); | ||||||||||||||||||||||||||||||||
typeck_results.node_substs_mut().remove(e.hir_id); | ||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// check-pass | ||
fn f<T> (it: &[T]) | ||
where | ||
[T] : std::ops::Index<usize>, | ||
{ | ||
let _ = &it[0]; | ||
} | ||
fn main(){} |
There was a problem hiding this comment.
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 calledsomething_ty