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

Rollup of 9 pull requests #108998

Merged
merged 22 commits into from
Mar 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
660d985
Guarantee the memory layout of `Cell`
madsmtm Jan 15, 2023
4fe232b
Do not ICE when we have fn pointer Fn obligations with bound vars in …
compiler-errors Mar 6, 2023
3097453
improve readability of winnowing
lcnr Mar 9, 2023
d223c26
fix(lexer): not skipped whitespace warning for '\x0c'
bvanjoi Mar 9, 2023
3aea469
Emit alias-eq when equating numeric var and projection
compiler-errors Mar 6, 2023
1b6d6f9
Fix canonicalizer bug for int/float vars too
compiler-errors Mar 8, 2023
d4b59a0
Propagate expected return type instead of real return type in check_b…
compiler-errors Mar 9, 2023
9574f39
Use param's real type in try_eval_lit_or_param
compiler-errors Mar 9, 2023
f714613
Bail in combine if consts have different types
compiler-errors Mar 9, 2023
a30c2c2
feat: implement better error for manual impl of `Fn*` traits
Ezrashaw Mar 9, 2023
14818e2
updating comment
lcnr Mar 10, 2023
a818484
Update triagebot rust-analyzer team mention
Veykril Mar 10, 2023
ad2bcb5
Forbid `#[target_feature]` on safe default implementations
LeSeulArtichaut Mar 10, 2023
b90277e
Rollup merge of #106921 - madsmtm:cell-memory-layout, r=dtolnay
matthiaskrgr Mar 10, 2023
233ed35
Rollup merge of #108828 - compiler-errors:new-solver-alias-eq-on-num-…
matthiaskrgr Mar 10, 2023
bee8473
Rollup merge of #108834 - compiler-errors:fn-ptr-fn-obl, r=spastorino
matthiaskrgr Mar 10, 2023
4ad3230
Rollup merge of #108900 - bvanjoi:issue-108275, r=petrochenkov
matthiaskrgr Mar 10, 2023
7699462
Rollup merge of #108930 - Ezrashaw:better-error-for-manual-fn-impl, r…
matthiaskrgr Mar 10, 2023
772b1ce
Rollup merge of #108937 - lcnr:winnowing-enum, r=WaffleLapkin
matthiaskrgr Mar 10, 2023
145e620
Rollup merge of #108947 - compiler-errors:ct-infer-no-shapeshifting, …
matthiaskrgr Mar 10, 2023
42ca383
Rollup merge of #108976 - Veykril:patch-2, r=jyn514
matthiaskrgr Mar 10, 2023
f74bb35
Rollup merge of #108983 - LeSeulArtichaut:108646-target-feature-defau…
matthiaskrgr Mar 10, 2023
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
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxIndexSet<Symbol> {
pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) {
if let DefKind::AssocFn = tcx.def_kind(id) {
let parent_id = tcx.local_parent(id);
if let DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) {
if let DefKind::Trait | DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) {
tcx.sess
.struct_span_err(
attr_span,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir_analysis/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ hir_analysis_assoc_type_binding_not_allowed =
associated type bindings are not allowed here
.label = associated type not allowed here

hir_analysis_parenthesized_fn_trait_expansion =
parenthesized trait syntax expands to `{$expanded_type}`

hir_analysis_typeof_reserved_keyword_used =
`typeof` is a reserved keyword but unimplemented
.suggestion = consider replacing `typeof(...)` with an actual type
Expand Down
107 changes: 72 additions & 35 deletions compiler/rustc_hir_analysis/src/astconv/errors.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use crate::astconv::AstConv;
use crate::errors::{ManualImplementation, MissingTypeParams};
use crate::errors::{
AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
ParenthesizedFnTraitExpansion,
};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::traits::FulfillmentError;
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{self, Ty};
use rustc_session::parse::feature_err;
use rustc_span::edit_distance::find_best_match_for_name;
Expand Down Expand Up @@ -78,43 +82,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Do not suggest the other syntax if we are in trait impl:
// the desugaring would contain an associated type constraint.
if !is_impl {
let args = trait_segment
.args
.as_ref()
.and_then(|args| args.args.get(0))
.and_then(|arg| match arg {
hir::GenericArg::Type(ty) => match ty.kind {
hir::TyKind::Tup(t) => t
.iter()
.map(|e| sess.source_map().span_to_snippet(e.span))
.collect::<Result<Vec<_>, _>>()
.map(|a| a.join(", ")),
_ => sess.source_map().span_to_snippet(ty.span),
}
.map(|s| format!("({})", s))
.ok(),
_ => None,
})
.unwrap_or_else(|| "()".to_string());
let ret = trait_segment
.args()
.bindings
.iter()
.find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
(true, hir::TypeBindingKind::Equality { term }) => {
let span = match term {
hir::Term::Ty(ty) => ty.span,
hir::Term::Const(c) => self.tcx().hir().span(c.hir_id),
};
sess.source_map().span_to_snippet(span).ok()
}
_ => None,
})
.unwrap_or_else(|| "()".to_string());
err.span_suggestion(
span,
"use parenthetical notation instead",
format!("{}{} -> {}", trait_segment.ident, args, ret),
fn_trait_to_string(self.tcx(), trait_segment, true),
Applicability::MaybeIncorrect,
);
}
Expand Down Expand Up @@ -629,3 +600,69 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
err.emit();
}
}

/// Emits an error regarding forbidden type binding associations
pub fn prohibit_assoc_ty_binding(
tcx: TyCtxt<'_>,
span: Span,
segment: Option<(&hir::PathSegment<'_>, Span)>,
) {
tcx.sess.emit_err(AssocTypeBindingNotAllowed { span, fn_trait_expansion: if let Some((segment, span)) = segment && segment.args().parenthesized {
Some(ParenthesizedFnTraitExpansion { span, expanded_type: fn_trait_to_string(tcx, segment, false) })
} else {
None
}});
}

pub(crate) fn fn_trait_to_string(
tcx: TyCtxt<'_>,
trait_segment: &hir::PathSegment<'_>,
parenthesized: bool,
) -> String {
let args = trait_segment
.args
.as_ref()
.and_then(|args| args.args.get(0))
.and_then(|arg| match arg {
hir::GenericArg::Type(ty) => match ty.kind {
hir::TyKind::Tup(t) => t
.iter()
.map(|e| tcx.sess.source_map().span_to_snippet(e.span))
.collect::<Result<Vec<_>, _>>()
.map(|a| a.join(", ")),
_ => tcx.sess.source_map().span_to_snippet(ty.span),
}
.map(|s| {
// `s.empty()` checks to see if the type is the unit tuple, if so we don't want a comma
if parenthesized || s.is_empty() { format!("({})", s) } else { format!("({},)", s) }
})
.ok(),
_ => None,
})
.unwrap_or_else(|| "()".to_string());

let ret = trait_segment
.args()
.bindings
.iter()
.find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
(true, hir::TypeBindingKind::Equality { term }) => {
let span = match term {
hir::Term::Ty(ty) => ty.span,
hir::Term::Const(c) => tcx.hir().span(c.hir_id),
};

(span != tcx.hir().span(trait_segment.hir_id))
.then_some(tcx.sess.source_map().span_to_snippet(span).ok())
.flatten()
}
_ => None,
})
.unwrap_or_else(|| "()".to_string());

if parenthesized {
format!("{}{} -> {}", trait_segment.ident, args, ret)
} else {
format!("{}<{}, Output={}>", trait_segment.ident, args, ret)
}
}
12 changes: 3 additions & 9 deletions compiler/rustc_hir_analysis/src/astconv/generics.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use super::IsMethodCall;
use crate::astconv::{
CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
GenericArgCountResult, GenericArgPosition,
errors::prohibit_assoc_ty_binding, CreateSubstsForGenericArgsCtxt, ExplicitLateBound,
GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition,
};
use crate::errors::AssocTypeBindingNotAllowed;
use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
use rustc_ast::ast::ParamKindOrd;
use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
Expand Down Expand Up @@ -433,7 +432,7 @@ pub(crate) fn check_generic_arg_count(
(gen_pos != GenericArgPosition::Type || infer_args) && !gen_args.has_lifetime_params();

if gen_pos != GenericArgPosition::Type && let Some(b) = gen_args.bindings.first() {
prohibit_assoc_ty_binding(tcx, b.span);
prohibit_assoc_ty_binding(tcx, b.span, None);
}

let explicit_late_bound =
Expand Down Expand Up @@ -589,11 +588,6 @@ pub(crate) fn check_generic_arg_count(
}
}

/// Emits an error regarding forbidden type binding associations
pub fn prohibit_assoc_ty_binding(tcx: TyCtxt<'_>, span: Span) {
tcx.sess.emit_err(AssocTypeBindingNotAllowed { span });
}

/// Prohibits explicit lifetime arguments if late-bound lifetime parameters
/// are present. This is used both for datatypes and function calls.
pub(crate) fn prohibit_explicit_late_bound_lifetimes(
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
mod errors;
pub mod generics;

use crate::astconv::generics::{
check_generic_arg_count, create_substs_for_generic_args, prohibit_assoc_ty_binding,
};
use crate::astconv::errors::prohibit_assoc_ty_binding;
use crate::astconv::generics::{check_generic_arg_count, create_substs_for_generic_args};
use crate::bounds::Bounds;
use crate::collect::HirPlaceholderCollector;
use crate::errors::{
Expand Down Expand Up @@ -295,7 +294,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
ty::BoundConstness::NotConst,
);
if let Some(b) = item_segment.args().bindings.first() {
prohibit_assoc_ty_binding(self.tcx(), b.span);
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((item_segment, span)));
}

substs
Expand Down Expand Up @@ -631,7 +630,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
);

if let Some(b) = item_segment.args().bindings.first() {
prohibit_assoc_ty_binding(self.tcx(), b.span);
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((item_segment, span)));
}

args
Expand Down Expand Up @@ -825,7 +824,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
constness,
);
if let Some(b) = trait_segment.args().bindings.first() {
prohibit_assoc_ty_binding(self.tcx(), b.span);
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((trait_segment, span)));
}
self.tcx().mk_trait_ref(trait_def_id, substs)
}
Expand Down Expand Up @@ -2596,7 +2595,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
for segment in segments {
// Only emit the first error to avoid overloading the user with error messages.
if let Some(b) = segment.args().bindings.first() {
prohibit_assoc_ty_binding(self.tcx(), b.span);
prohibit_assoc_ty_binding(self.tcx(), b.span, None);
return true;
}
}
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@ pub struct AssocTypeBindingNotAllowed {
#[primary_span]
#[label]
pub span: Span,

#[subdiagnostic]
pub fn_trait_expansion: Option<ParenthesizedFnTraitExpansion>,
}

#[derive(Subdiagnostic)]
#[help(hir_analysis_parenthesized_fn_trait_expansion)]
pub struct ParenthesizedFnTraitExpansion {
#[primary_span]
pub span: Span,

pub expanded_type: String,
}

#[derive(Diagnostic)]
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_hir_typeck/src/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_ty,
op,
);
self.demand_suptype(expr.span, builtin_return_ty, return_ty);
self.demand_eqtype(expr.span, builtin_return_ty, return_ty);
builtin_return_ty
} else {
return_ty
}

return_ty
}
}
}
Expand Down
31 changes: 22 additions & 9 deletions compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,28 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
}
}

ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
t,
),

ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
t,
),
ty::Infer(ty::IntVar(vid)) => {
let nt = self.infcx.opportunistic_resolve_int_var(vid);
if nt != t {
return self.fold_ty(nt);
} else {
self.canonicalize_ty_var(
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
t,
)
}
}
ty::Infer(ty::FloatVar(vid)) => {
let nt = self.infcx.opportunistic_resolve_float_var(vid);
if nt != t {
return self.fold_ty(nt);
} else {
self.canonicalize_ty_var(
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
t,
)
}
}

ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("encountered a fresh type during canonicalization")
Expand Down
48 changes: 33 additions & 15 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ use rustc_hir::def_id::DefId;
use rustc_middle::infer::canonical::OriginalQueryValues;
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
Expand Down Expand Up @@ -119,20 +118,30 @@ impl<'tcx> InferCtxt<'tcx> {
self.unify_float_variable(!a_is_expected, v_id, v)
}

// All other cases of inference are errors
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b)))
// We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
(
ty::Alias(AliasKind::Projection, _),
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
)
| (
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
ty::Alias(AliasKind::Projection, _),
) if self.tcx.trait_solver_next() => {
bug!()
}

(ty::Alias(AliasKind::Projection, _), _) if self.tcx.trait_solver_next() => {
(_, ty::Alias(AliasKind::Projection, _)) | (ty::Alias(AliasKind::Projection, _), _)
if self.tcx.trait_solver_next() =>
{
relation.register_type_equate_obligation(a, b);
Ok(b)
}
(_, ty::Alias(AliasKind::Projection, _)) if self.tcx.trait_solver_next() => {
relation.register_type_equate_obligation(b, a);
Ok(a)
}

// All other cases of inference are errors
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b)))
}

_ => ty::relate::super_relate_tys(relation, a, b),
}
}
Expand Down Expand Up @@ -161,9 +170,9 @@ impl<'tcx> InferCtxt<'tcx> {
//
// This probe is probably not strictly necessary but it seems better to be safe and not accidentally find
// ourselves with a check to find bugs being required for code to compile because it made inference progress.
self.probe(|_| {
let compatible_types = self.probe(|_| {
if a.ty() == b.ty() {
return;
return Ok(());
}

// We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the
Expand All @@ -173,15 +182,24 @@ impl<'tcx> InferCtxt<'tcx> {
(relation.param_env(), a.ty(), b.ty()),
&mut OriginalQueryValues::default(),
);

if let Err(NoSolution) = self.tcx.check_tys_might_be_eq(canonical) {
self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
self.tcx.sess.delay_span_bug(
DUMMY_SP,
&format!("cannot relate consts of different types (a={:?}, b={:?})", a, b,),
);
}
)
})
});

// If the consts have differing types, just bail with a const error with
// the expected const's type. Specifically, we don't want const infer vars
// to do any type shapeshifting before and after resolution.
if let Err(guar) = compatible_types {
return Ok(self.tcx.const_error_with_guaranteed(
if relation.a_is_expected() { a.ty() } else { b.ty() },
guar,
));
}

match (a.kind(), b.kind()) {
(
ty::ConstKind::Infer(InferConst::Var(a_vid)),
Expand Down
Loading