Add inferred args to typeck
This commit is contained in:
parent
417b098cfc
commit
3605675bb1
18 changed files with 132 additions and 52 deletions
|
@ -437,7 +437,7 @@ pub trait Visitor<'v>: Sized {
|
||||||
walk_label(self, label)
|
walk_label(self, label)
|
||||||
}
|
}
|
||||||
fn visit_infer(&mut self, inf: &'v InferArg) {
|
fn visit_infer(&mut self, inf: &'v InferArg) {
|
||||||
self.visit_id(inf.hir_id);
|
walk_inf(self, inf);
|
||||||
}
|
}
|
||||||
fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) {
|
fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) {
|
||||||
match generic_arg {
|
match generic_arg {
|
||||||
|
@ -447,11 +447,6 @@ pub trait Visitor<'v>: Sized {
|
||||||
GenericArg::Infer(inf) => self.visit_infer(inf),
|
GenericArg::Infer(inf) => self.visit_infer(inf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
fn tcx(&self) -> Option<&TyCtxt<'tcx>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
|
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
|
||||||
walk_lifetime(self, lifetime)
|
walk_lifetime(self, lifetime)
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,6 +244,11 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
|
||||||
hir_visit::walk_ty(self, t);
|
hir_visit::walk_ty(self, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
|
||||||
|
lint_callback!(self, check_infer, inf);
|
||||||
|
hir_visit::walk_inf(self, inf);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_name(&mut self, sp: Span, name: Symbol) {
|
fn visit_name(&mut self, sp: Span, name: Symbol) {
|
||||||
lint_callback!(self, check_name, sp, name);
|
lint_callback!(self, check_name, sp, name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ macro_rules! late_lint_methods {
|
||||||
fn check_expr(a: &$hir hir::Expr<$hir>);
|
fn check_expr(a: &$hir hir::Expr<$hir>);
|
||||||
fn check_expr_post(a: &$hir hir::Expr<$hir>);
|
fn check_expr_post(a: &$hir hir::Expr<$hir>);
|
||||||
fn check_ty(a: &$hir hir::Ty<$hir>);
|
fn check_ty(a: &$hir hir::Ty<$hir>);
|
||||||
|
fn check_infer(a: &$hir hir::InferArg);
|
||||||
fn check_generic_arg(a: &$hir hir::GenericArg<$hir>);
|
fn check_generic_arg(a: &$hir hir::GenericArg<$hir>);
|
||||||
fn check_generic_param(a: &$hir hir::GenericParam<$hir>);
|
fn check_generic_param(a: &$hir hir::GenericParam<$hir>);
|
||||||
fn check_generics(a: &$hir hir::Generics<$hir>);
|
fn check_generics(a: &$hir hir::Generics<$hir>);
|
||||||
|
|
|
@ -272,11 +272,11 @@ impl<'hir> Map<'hir> {
|
||||||
GenericParamKind::Type { .. } => DefKind::TyParam,
|
GenericParamKind::Type { .. } => DefKind::TyParam,
|
||||||
GenericParamKind::Const { .. } => DefKind::ConstParam,
|
GenericParamKind::Const { .. } => DefKind::ConstParam,
|
||||||
},
|
},
|
||||||
Node::Infer(_) => todo!(),
|
|
||||||
Node::Crate(_) => DefKind::Mod,
|
Node::Crate(_) => DefKind::Mod,
|
||||||
Node::Stmt(_)
|
Node::Stmt(_)
|
||||||
| Node::PathSegment(_)
|
| Node::PathSegment(_)
|
||||||
| Node::Ty(_)
|
| Node::Ty(_)
|
||||||
|
| Node::Infer(_)
|
||||||
| Node::TraitRef(_)
|
| Node::TraitRef(_)
|
||||||
| Node::Pat(_)
|
| Node::Pat(_)
|
||||||
| Node::Binding(_)
|
| Node::Binding(_)
|
||||||
|
|
|
@ -133,11 +133,6 @@ rustc_queries! {
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
}
|
}
|
||||||
|
|
||||||
query generic_arg_for_infer_arg(key: DefId) -> hir::GenericArg<'tcx> {
|
|
||||||
desc { |tcx| "computes concrete type for inference, `{}`", tcx.def_path_str(key) }
|
|
||||||
storage(ArenaCacheSelector<'tcx>)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
|
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
|
||||||
/// predicates (where-clauses) that must be proven true in order
|
/// predicates (where-clauses) that must be proven true in order
|
||||||
/// to reference it. This is almost always the "predicates query"
|
/// to reference it. This is almost always the "predicates query"
|
||||||
|
|
|
@ -1191,16 +1191,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
||||||
fn visit_generic_arg(&mut self, generic_arg: &'tcx hir::GenericArg<'tcx>) {
|
fn visit_generic_arg(&mut self, generic_arg: &'tcx hir::GenericArg<'tcx>) {
|
||||||
match generic_arg {
|
match generic_arg {
|
||||||
hir::GenericArg::Type(t) => self.visit_ty(t),
|
hir::GenericArg::Type(t) => self.visit_ty(t),
|
||||||
hir::GenericArg::Infer(inf) => {
|
hir::GenericArg::Infer(inf) => self.visit_infer(inf),
|
||||||
self.span = inf.span;
|
|
||||||
let parent_hir_id = self.tcx.hir().get_parent_node(inf.hir_id);
|
|
||||||
if let Some(typeck_results) = self.maybe_typeck_results {
|
|
||||||
let node_substs = typeck_results.node_substs(parent_hir_id);
|
|
||||||
for ty in node_substs.types() {
|
|
||||||
self.visit(ty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {}
|
hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1224,6 +1215,23 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
||||||
intravisit::walk_ty(self, hir_ty);
|
intravisit::walk_ty(self, hir_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
|
||||||
|
self.span = inf.span;
|
||||||
|
if let Some(typeck_results) = self.maybe_typeck_results {
|
||||||
|
if let Some(ty) = typeck_results.node_type_opt(inf.hir_id) {
|
||||||
|
if self.visit(ty).is_break() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// FIXME see above note for same issue.
|
||||||
|
if self.visit(rustc_typeck::hir_ty_to_ty(self.tcx, &inf.to_ty())).is_break() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intravisit::walk_inf(self, inf);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef<'tcx>) {
|
fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef<'tcx>) {
|
||||||
self.span = trait_ref.path.span;
|
self.span = trait_ref.path.span;
|
||||||
if self.maybe_typeck_results.is_none() {
|
if self.maybe_typeck_results.is_none() {
|
||||||
|
|
|
@ -18,23 +18,6 @@ use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS;
|
||||||
use rustc_span::{symbol::kw, MultiSpan, Span};
|
use rustc_span::{symbol::kw, MultiSpan, Span};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
/*
|
|
||||||
pub fn generic_arg_for_infer_arg<'tcx>(tcx: TyCtxt<'tcx>, did: LocalDefId) -> GenericArg<'tcx> {
|
|
||||||
todo!()
|
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(did);
|
|
||||||
let arg = match tcx.hir().get(hir_id) {
|
|
||||||
hir::Node::GenericParam(hir::GenericParam {
|
|
||||||
kind: hir::GenericParamKind::Const { ty: _, default: _ },
|
|
||||||
..
|
|
||||||
}) => todo!(),
|
|
||||||
_ => bug!("Expected GenericParam for generic_arg_for_infer_arg"),
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(!matches!(arg, GenericArg::Infer(_)));
|
|
||||||
arg
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
/// Report an error that a generic argument did not match the generic parameter that was
|
/// Report an error that a generic argument did not match the generic parameter that was
|
||||||
/// expected.
|
/// expected.
|
||||||
|
|
|
@ -479,6 +479,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
param.def_id,
|
param.def_id,
|
||||||
Some(arg.id()),
|
Some(arg.id()),
|
||||||
arg.span(),
|
arg.span(),
|
||||||
|
None,
|
||||||
|_, _| {
|
|_, _| {
|
||||||
// Default generic parameters may not be marked
|
// Default generic parameters may not be marked
|
||||||
// with stability attributes, i.e. when the
|
// with stability attributes, i.e. when the
|
||||||
|
|
|
@ -581,6 +581,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
|
||||||
|
match self.typeck_results.borrow().node_types().get(id) {
|
||||||
|
Some(&t) => Some(t),
|
||||||
|
None if self.is_tainted_by_errors() => Some(self.tcx.ty_error()),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
|
/// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
|
||||||
pub fn register_wf_obligation(
|
pub fn register_wf_obligation(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -331,6 +331,15 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
|
||||||
let ty = self.resolve(ty, &hir_ty.span);
|
let ty = self.resolve(ty, &hir_ty.span);
|
||||||
self.write_ty_to_typeck_results(hir_ty.hir_id, ty);
|
self.write_ty_to_typeck_results(hir_ty.hir_id, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
|
||||||
|
intravisit::walk_inf(self, inf);
|
||||||
|
// Ignore cases where the inference is a const.
|
||||||
|
if let Some(ty) = self.fcx.node_ty_opt(inf.hir_id) {
|
||||||
|
let ty = self.resolve(ty, &inf.span);
|
||||||
|
self.write_ty_to_typeck_results(inf.hir_id, ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
|
|
|
@ -133,6 +133,7 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
|
||||||
match generic_arg {
|
match generic_arg {
|
||||||
hir::GenericArg::Infer(inf) => {
|
hir::GenericArg::Infer(inf) => {
|
||||||
self.0.push(inf.span);
|
self.0.push(inf.span);
|
||||||
|
intravisit::walk_inf(self, inf);
|
||||||
}
|
}
|
||||||
hir::GenericArg::Type(t) => self.visit_ty(t),
|
hir::GenericArg::Type(t) => self.visit_ty(t),
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -273,6 +273,17 @@ LL | priv_parent_substs::mac!();
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: type `priv_parent_substs::Priv` is private
|
||||||
|
--> $DIR/associated-item-privacy-trait.rs:117:30
|
||||||
|
|
|
||||||
|
LL | let _: <Pub as PubTr<_>>::AssocTy;
|
||||||
|
| ^ private type
|
||||||
|
...
|
||||||
|
LL | priv_parent_substs::mac!();
|
||||||
|
| --------------------------- in this macro invocation
|
||||||
|
|
|
||||||
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type `priv_parent_substs::Priv` is private
|
error: type `priv_parent_substs::Priv` is private
|
||||||
--> $DIR/associated-item-privacy-trait.rs:119:17
|
--> $DIR/associated-item-privacy-trait.rs:119:17
|
||||||
|
|
|
|
||||||
|
@ -317,5 +328,5 @@ LL | priv_parent_substs::mac!();
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 29 previous errors
|
error: aborting due to 30 previous errors
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::collections::BTreeMap;
|
||||||
|
|
||||||
use rustc_errors::DiagnosticBuilder;
|
use rustc_errors::DiagnosticBuilder;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, walk_inf, NestedVisitorMap, Visitor};
|
||||||
use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
|
use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::hir::map::Map;
|
use rustc_middle::hir::map::Map;
|
||||||
|
@ -295,6 +295,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ImplicitHasherTypeVisitor<'a, 'tcx> {
|
||||||
walk_ty(self, t);
|
walk_ty(self, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
|
||||||
|
if let Some(target) = ImplicitHasherType::new(self.cx, &inf.to_ty()) {
|
||||||
|
self.found.push(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
walk_inf(self, inf);
|
||||||
|
}
|
||||||
|
|
||||||
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
||||||
NestedVisitorMap::None
|
NestedVisitorMap::None
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use clippy_utils::diagnostics::span_lint;
|
use clippy_utils::diagnostics::span_lint;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::intravisit::{walk_ty, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{walk_ty, walk_inf, NestedVisitorMap, Visitor};
|
||||||
use rustc_hir::{GenericParamKind, TyKind};
|
use rustc_hir::{GenericParamKind, TyKind};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::hir::map::Map;
|
use rustc_middle::hir::map::Map;
|
||||||
|
@ -39,6 +39,11 @@ struct TypeComplexityVisitor {
|
||||||
impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
|
impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
|
||||||
type Map = Map<'tcx>;
|
type Map = Map<'tcx>;
|
||||||
|
|
||||||
|
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
|
||||||
|
self.score += 1;
|
||||||
|
walk_inf(self, inf);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'_>) {
|
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'_>) {
|
||||||
let (add_score, sub_nest) = match ty.kind {
|
let (add_score, sub_nest) = match ty.kind {
|
||||||
// _, &x and *x have only small overhead; don't mess with nesting level
|
// _, &x and *x have only small overhead; don't mess with nesting level
|
||||||
|
|
|
@ -8,8 +8,9 @@ use rustc_hir::{
|
||||||
self as hir,
|
self as hir,
|
||||||
def::{CtorOf, DefKind, Res},
|
def::{CtorOf, DefKind, Res},
|
||||||
def_id::LocalDefId,
|
def_id::LocalDefId,
|
||||||
intravisit::{walk_ty, NestedVisitorMap, Visitor},
|
intravisit::{walk_ty, walk_inf, NestedVisitorMap, Visitor},
|
||||||
Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Path, QPath, TyKind,
|
Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Node, Path, PathSegment,
|
||||||
|
QPath, TyKind,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::hir::map::Map;
|
use rustc_middle::hir::map::Map;
|
||||||
|
@ -263,6 +264,11 @@ struct SkipTyCollector {
|
||||||
impl<'tcx> Visitor<'tcx> for SkipTyCollector {
|
impl<'tcx> Visitor<'tcx> for SkipTyCollector {
|
||||||
type Map = Map<'tcx>;
|
type Map = Map<'tcx>;
|
||||||
|
|
||||||
|
fn visit_infer(&mut self, inf: &hir::InferArg) {
|
||||||
|
self.types_to_skip.push(inf.hir_id);
|
||||||
|
|
||||||
|
walk_inf(self, inf)
|
||||||
|
}
|
||||||
fn visit_ty(&mut self, hir_ty: &hir::Ty<'_>) {
|
fn visit_ty(&mut self, hir_ty: &hir::Ty<'_>) {
|
||||||
self.types_to_skip.push(hir_ty.hir_id);
|
self.types_to_skip.push(hir_ty.hir_id);
|
||||||
|
|
||||||
|
@ -274,6 +280,52 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
struct LintTyCollector<'a, 'tcx> {
|
||||||
|
cx: &'a LateContext<'tcx>,
|
||||||
|
self_ty: Ty<'tcx>,
|
||||||
|
types_to_lint: Vec<HirId>,
|
||||||
|
types_to_skip: Vec<HirId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx> Visitor<'tcx> for LintTyCollector<'a, 'tcx> {
|
||||||
|
type Map = Map<'tcx>;
|
||||||
|
|
||||||
|
fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'_>) {
|
||||||
|
if_chain! {
|
||||||
|
if let Some(ty) = self.cx.typeck_results().node_type_opt(hir_ty.hir_id);
|
||||||
|
if should_lint_ty(hir_ty, ty, self.self_ty);
|
||||||
|
then {
|
||||||
|
self.types_to_lint.push(hir_ty.hir_id);
|
||||||
|
} else {
|
||||||
|
self.types_to_skip.push(hir_ty.hir_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walk_ty(self, hir_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
|
||||||
|
if_chain! {
|
||||||
|
if let Some(ty) = self.cx.typeck_results().node_type_opt(inf.hir_id);
|
||||||
|
if should_lint_ty(&inf.to_ty(), ty, self.self_ty);
|
||||||
|
then {
|
||||||
|
self.types_to_lint.push(inf.hir_id);
|
||||||
|
} else {
|
||||||
|
self.types_to_skip.push(inf.hir_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walk_inf(self, inf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
||||||
|
NestedVisitorMap::None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
>>>>>>> Add inferred args to typeck
|
||||||
fn span_lint(cx: &LateContext<'_>, span: Span) {
|
fn span_lint(cx: &LateContext<'_>, span: Span) {
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
|
|
|
@ -288,6 +288,8 @@ impl HirEqInterExpr<'_, '_, '_> {
|
||||||
(GenericArg::Const(l), GenericArg::Const(r)) => self.eq_body(l.value.body, r.value.body),
|
(GenericArg::Const(l), GenericArg::Const(r)) => self.eq_body(l.value.body, r.value.body),
|
||||||
(GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => Self::eq_lifetime(l_lt, r_lt),
|
(GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => Self::eq_lifetime(l_lt, r_lt),
|
||||||
(GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty, r_ty),
|
(GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty, r_ty),
|
||||||
|
(GenericArg::Infer(l_inf), GenericArg::Infer(r_inf)) =>
|
||||||
|
self.eq_ty(&l_inf.to_ty(), &r_inf.to_ty()),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -888,10 +890,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||||
self.hash_tykind(&ty.kind);
|
self.hash_tykind(&ty.kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash_infer(&mut self) {
|
|
||||||
"_".hash(&mut self.s);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn hash_tykind(&mut self, ty: &TyKind<'_>) {
|
pub fn hash_tykind(&mut self, ty: &TyKind<'_>) {
|
||||||
match ty {
|
match ty {
|
||||||
TyKind::Slice(ty) => {
|
TyKind::Slice(ty) => {
|
||||||
|
@ -957,7 +955,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||||
GenericArg::Lifetime(l) => self.hash_lifetime(l),
|
GenericArg::Lifetime(l) => self.hash_lifetime(l),
|
||||||
GenericArg::Type(ref ty) => self.hash_ty(ty),
|
GenericArg::Type(ref ty) => self.hash_ty(ty),
|
||||||
GenericArg::Const(ref ca) => self.hash_body(ca.value.body),
|
GenericArg::Const(ref ca) => self.hash_body(ca.value.body),
|
||||||
GenericArg::Infer(ref _inf) => self.hash_infer(),
|
GenericArg::Infer(ref inf) => self.hash_ty(&inf.to_ty()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Per https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/infer/at/struct.At.html#method.normalize
|
// FIXME: Per https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/infer/at/struct.At.html#method.normalize
|
||||||
// this function can be removed once the `normalizie` method does not panic when normalization does
|
// this function can be removed once the `normalize` method does not panic when normalization does
|
||||||
// not succeed
|
// not succeed
|
||||||
/// Checks if `Ty` is normalizable. This function is useful
|
/// Checks if `Ty` is normalizable. This function is useful
|
||||||
/// to avoid crashes on `layout_of`.
|
/// to avoid crashes on `layout_of`.
|
||||||
|
|
|
@ -46,13 +46,13 @@ error: transmute from a pointer type (`*const i32`) to a reference type (`&issue
|
||||||
--> $DIR/transmute_ptr_to_ref.rs:32:32
|
--> $DIR/transmute_ptr_to_ref.rs:32:32
|
||||||
|
|
|
|
||||||
LL | let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) };
|
LL | let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const Foo<_>)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const issue1231::Foo<u8>)`
|
||||||
|
|
||||||
error: transmute from a pointer type (`*const i32`) to a reference type (`&issue1231::Foo<&u8>`)
|
error: transmute from a pointer type (`*const i32`) to a reference type (`&issue1231::Foo<&u8>`)
|
||||||
--> $DIR/transmute_ptr_to_ref.rs:34:33
|
--> $DIR/transmute_ptr_to_ref.rs:34:33
|
||||||
|
|
|
|
||||||
LL | let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) };
|
LL | let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const Foo<&_>)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const issue1231::Foo<&u8>)`
|
||||||
|
|
||||||
error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`)
|
error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`)
|
||||||
--> $DIR/transmute_ptr_to_ref.rs:38:14
|
--> $DIR/transmute_ptr_to_ref.rs:38:14
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue