Auto merge of #132435 - workingjubilee:rollup-3mgogw9, r=workingjubilee

Rollup of 9 pull requests

Successful merges:

 - #131168 (Fix `target_os` for `mipsel-sony-psx`)
 - #132209 (Fix validation when lowering `?` trait bounds)
 - #132294 (Bump Fuchsia)
 - #132357 (Improve missing_abi lint)
 - #132385 (compiler: Move `rustc_target::spec::abi::Abi` to `rustc_abi::ExternAbi`)
 - #132403 (continue `TypingMode` refactor)
 - #132417 (macOS: Document the difference between Clang's `-darwin` and `-macosx` targets)
 - #132421 (Remove `""` case from RISC-V `llvm_abiname` match statement)
 - #132422 (llvm: Match new LLVM 128-bit integer alignment on sparc)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-11-01 02:13:05 +00:00
commit a8e1186e3c
75 changed files with 364 additions and 220 deletions

View File

@ -3204,9 +3204,11 @@ dependencies = [
"rand",
"rand_xoshiro",
"rustc_data_structures",
"rustc_feature",
"rustc_index",
"rustc_macros",
"rustc_serialize",
"rustc_span",
"tracing",
]
@ -3749,11 +3751,11 @@ dependencies = [
name = "rustc_hir_pretty"
version = "0.0.0"
dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_hir",
"rustc_span",
"rustc_target",
]
[[package]]
@ -3938,6 +3940,7 @@ dependencies = [
name = "rustc_lint_defs"
version = "0.0.0"
dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_data_structures",
"rustc_error_messages",
@ -3945,7 +3948,6 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"rustc_target",
"serde",
]
@ -4054,6 +4056,7 @@ version = "0.0.0"
dependencies = [
"either",
"itertools",
"rustc_abi",
"rustc_apfloat",
"rustc_arena",
"rustc_ast",
@ -4069,7 +4072,6 @@ dependencies = [
"rustc_pattern_analysis",
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"tracing",
]

View File

@ -9,9 +9,11 @@ bitflags = "2.4.1"
rand = { version = "0.8.4", default-features = false, optional = true }
rand_xoshiro = { version = "0.6.0", optional = true }
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
rustc_feature = { path = "../rustc_feature", optional = true }
rustc_index = { path = "../rustc_index", default-features = false }
rustc_macros = { path = "../rustc_macros", optional = true }
rustc_serialize = { path = "../rustc_serialize", optional = true }
rustc_span = { path = "../rustc_span", optional = true }
tracing = "0.1"
# tidy-alphabetical-end
@ -22,8 +24,10 @@ default = ["nightly", "randomize"]
# without depending on rustc_data_structures, rustc_macros and rustc_serialize
nightly = [
"dep:rustc_data_structures",
"dep:rustc_feature",
"dep:rustc_macros",
"dep:rustc_serialize",
"dep:rustc_span",
"rustc_index/nightly",
]
randomize = ["dep:rand", "dep:rand_xoshiro", "nightly"]

View File

@ -7,9 +7,11 @@ use rustc_span::{Span, Symbol};
#[cfg(test)]
mod tests;
use ExternAbi as Abi;
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)]
#[derive(HashStable_Generic, Encodable, Decodable)]
pub enum Abi {
pub enum ExternAbi {
// Some of the ABIs come first because every time we add a new ABI, we have to re-bless all the
// hashing tests. These are used in many places, so giving them stable values reduces test
// churn. The specific values are meaningless.

View File

@ -1,6 +1,7 @@
// tidy-alphabetical-start
#![cfg_attr(feature = "nightly", allow(internal_features))]
#![cfg_attr(feature = "nightly", doc(rust_logo))]
#![cfg_attr(feature = "nightly", feature(assert_matches))]
#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
#![cfg_attr(feature = "nightly", feature(rustdoc_internals))]
#![cfg_attr(feature = "nightly", feature(step_trait))]
@ -28,8 +29,15 @@ mod layout;
#[cfg(test)]
mod tests;
#[cfg(feature = "nightly")]
mod extern_abi;
pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind};
#[cfg(feature = "nightly")]
pub use extern_abi::{
AbiDisabled, AbiUnsupported, ExternAbi, all_names, enabled_names, is_enabled, is_stable, lookup,
};
#[cfg(feature = "nightly")]
pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx};
pub use layout::{LayoutCalculator, LayoutCalculatorError};

View File

@ -2810,6 +2810,8 @@ pub struct ModSpans {
/// E.g., `extern { .. }` or `extern "C" { .. }`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct ForeignMod {
/// Span of the `extern` keyword.
pub extern_span: Span,
/// `unsafe` keyword accepted syntactically for macro DSLs, but not
/// semantically by Rust.
pub safety: Safety,

View File

@ -525,7 +525,7 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
}
fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
let ForeignMod { safety, abi: _, items } = foreign_mod;
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
visit_safety(vis, safety);
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
}

View File

@ -366,7 +366,7 @@ impl WalkItemKind for ItemKind {
}
ModKind::Unloaded => {}
},
ItemKind::ForeignMod(ForeignMod { safety: _, abi: _, items }) => {
ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => {
walk_list!(visitor, visit_foreign_item, items);
}
ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),

View File

@ -677,9 +677,8 @@ impl<'a> AstValidator<'a> {
Self::check_decl_no_pat(&bfty.decl, |span, _, _| {
self.dcx().emit_err(errors::PatternFnPointer { span });
});
if let Extern::Implicit(_) = bfty.ext {
let sig_span = self.sess.source_map().next_point(ty.span.shrink_to_lo());
self.maybe_lint_missing_abi(sig_span, ty.id);
if let Extern::Implicit(extern_span) = bfty.ext {
self.maybe_lint_missing_abi(extern_span, ty.id);
}
}
TyKind::TraitObject(bounds, ..) => {
@ -953,7 +952,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again.
}
ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => {
ItemKind::ForeignMod(ForeignMod { extern_span, abi, safety, .. }) => {
self.with_in_extern_mod(*safety, |this| {
let old_item = mem::replace(&mut this.extern_mod, Some(item.span));
this.visibility_not_permitted(
@ -977,7 +976,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
if abi.is_none() {
this.maybe_lint_missing_abi(item.span, item.id);
this.maybe_lint_missing_abi(*extern_span, item.id);
}
visit::walk_item(this, item);
this.extern_mod = old_item;
@ -1350,13 +1349,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if let FnKind::Fn(
_,
_,
FnSig { span: sig_span, header: FnHeader { ext: Extern::Implicit(_), .. }, .. },
FnSig { header: FnHeader { ext: Extern::Implicit(extern_span), .. }, .. },
_,
_,
_,
) = fk
{
self.maybe_lint_missing_abi(*sig_span, id);
self.maybe_lint_missing_abi(*extern_span, id);
}
// Functions without bodies cannot have patterns.

View File

@ -148,6 +148,11 @@ pub(crate) unsafe fn create_module<'ll>(
target_data_layout =
target_data_layout.replace("-p270:32:32-p271:32:32-p272:64:64", "");
}
if sess.target.arch.starts_with("sparc") {
// LLVM 20 updates the sparc layout to correctly align 128 bit integers to 128 bit.
// See https://github.com/llvm/llvm-project/pull/106951
target_data_layout = target_data_layout.replace("-i128:128", "");
}
}
// Ensure the data-layout values hardcoded remain the defaults.

View File

@ -322,7 +322,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
// Set the appropriate flag based on ABI
// This needs to match LLVM `RISCVELFStreamer.cpp`
match &*sess.target.llvm_abiname {
"" | "ilp32" | "lp64" => (),
"ilp32" | "lp64" => (),
"ilp32f" | "lp64f" => e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE,
"ilp32d" | "lp64d" => e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE,
// Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI.

View File

@ -16,7 +16,7 @@ use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::*;
use rustc_middle::span_bug;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt, TypingMode};
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt};
use rustc_mir_dataflow::Analysis;
use rustc_mir_dataflow::impls::MaybeStorageLive;
use rustc_mir_dataflow::storage::always_storage_live_locals;
@ -589,7 +589,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// Typeck only does a "non-const" check since it operates on HIR and cannot distinguish
// which path expressions are getting called on and which path expressions are only used
// as function pointers. This is required for correctness.
let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env));
let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx));
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args);

View File

@ -32,14 +32,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self {
let def_id = body.source.def_id().expect_local();
let param_env = tcx.param_env(def_id);
Self::new_with_param_env(tcx, body, param_env)
}
pub fn new_with_param_env(
tcx: TyCtxt<'tcx>,
body: &'mir mir::Body<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> Self {
let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local());
ConstCx { body, tcx, param_env, const_kind }
}

View File

@ -12,7 +12,7 @@ use rustc_middle::mir::CallSource;
use rustc_middle::span_bug;
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
use rustc_middle::ty::{
self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty, TypingMode,
self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty,
suggest_constraining_type_param,
};
use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind};
@ -116,7 +116,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
let obligation =
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env));
let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx));
let mut selcx = SelectionContext::new(&infcx);
let implsrc = selcx.select(&obligation);

View File

@ -3,7 +3,7 @@ use rustc_errors::DiagCtxtHandle;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::infer::at::ToTrace;
use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::{ObligationCause, Reveal};
use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{
@ -116,6 +116,7 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> {
/// This test should be symmetric, as it is primarily about layout compatibility.
pub(super) fn mir_assign_valid_types<'tcx>(
tcx: TyCtxt<'tcx>,
typing_mode: TypingMode<'tcx>,
param_env: ParamEnv<'tcx>,
src: TyAndLayout<'tcx>,
dest: TyAndLayout<'tcx>,
@ -124,7 +125,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
// all normal lifetimes are erased, higher-ranked types with their
// late-bound lifetimes are still around and can lead to type
// differences.
if util::relate_types(tcx, param_env, Variance::Covariant, src.ty, dest.ty) {
if util::relate_types(tcx, typing_mode, param_env, Variance::Covariant, src.ty, dest.ty) {
// Make sure the layout is equal, too -- just to be safe. Miri really
// needs layout equality. For performance reason we skip this check when
// the types are equal. Equal types *can* have different layouts when
@ -144,6 +145,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
#[cfg_attr(not(debug_assertions), inline(always))]
pub(super) fn from_known_layout<'tcx>(
tcx: TyCtxtAt<'tcx>,
typing_mode: TypingMode<'tcx>,
param_env: ParamEnv<'tcx>,
known_layout: Option<TyAndLayout<'tcx>>,
compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
@ -153,7 +155,13 @@ pub(super) fn from_known_layout<'tcx>(
Some(known_layout) => {
if cfg!(debug_assertions) {
let check_layout = compute()?;
if !mir_assign_valid_types(tcx.tcx, param_env, check_layout, known_layout) {
if !mir_assign_valid_types(
tcx.tcx,
typing_mode,
param_env,
check_layout,
known_layout,
) {
span_bug!(
tcx.span,
"expected type differs from actual type.\nexpected: {}\nactual: {}",
@ -203,6 +211,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
}
pub fn typing_mode(&self) -> TypingMode<'tcx> {
debug_assert_eq!(self.param_env.reveal(), Reveal::All);
TypingMode::PostAnalysis
}
/// Returns the span of the currently executed statement/terminator.
/// This is the span typically used for error reporting.
#[inline(always)]
@ -327,7 +340,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
return true;
}
// Slow path: spin up an inference context to check if these traits are sufficiently equal.
let infcx = self.tcx.infer_ctxt().build(TypingMode::from_param_env(self.param_env));
let infcx = self.tcx.infer_ctxt().build(self.typing_mode());
let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy_with_span(self.cur_span());
// equate the two trait refs after normalization

View File

@ -773,6 +773,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
)?;
if !mir_assign_valid_types(
*self.tcx,
self.typing_mode(),
self.param_env,
self.layout_of(normalized_place_ty)?,
op.layout,
@ -832,7 +833,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
})
};
let layout =
from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty).into())?;
from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
self.layout_of(ty).into()
})?;
let imm = match val_val {
mir::ConstValue::Indirect { alloc_id, offset } => {
// This is const data, no mutation allowed.

View File

@ -540,6 +540,7 @@ where
)?;
if !mir_assign_valid_types(
*self.tcx,
self.typing_mode(),
self.param_env,
self.layout_of(normalized_place_ty)?,
place.layout,
@ -870,8 +871,13 @@ where
) -> InterpResult<'tcx> {
// We do NOT compare the types for equality, because well-typed code can
// actually "transmute" `&mut T` to `&T` in an assignment without a cast.
let layout_compat =
mir_assign_valid_types(*self.tcx, self.param_env, src.layout(), dest.layout());
let layout_compat = mir_assign_valid_types(
*self.tcx,
self.typing_mode(),
self.param_env,
src.layout(),
dest.layout(),
);
if !allow_transmute && !layout_compat {
span_bug!(
self.cur_span(),

View File

@ -596,12 +596,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
return interp_ok(layout);
}
let layout = from_known_layout(self.tcx, self.param_env, layout, || {
let local_ty = frame.body.local_decls[local].ty;
let local_ty =
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
self.layout_of(local_ty).into()
})?;
let layout =
from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
let local_ty = frame.body.local_decls[local].ty;
let local_ty =
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
self.layout_of(local_ty).into()
})?;
// Layouts of locals are requested a lot, so we cache them.
state.layout.set(Some(layout));

View File

@ -8,24 +8,15 @@ use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, TypingMode, Variance};
use rustc_trait_selection::traits::ObligationCtxt;
/// Returns whether the two types are equal up to subtyping.
///
/// This is used in case we don't know the expected subtyping direction
/// and still want to check whether anything is broken.
pub fn is_equal_up_to_subtyping<'tcx>(
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
pub fn sub_types<'tcx>(
tcx: TyCtxt<'tcx>,
typing_mode: TypingMode<'tcx>,
param_env: ParamEnv<'tcx>,
src: Ty<'tcx>,
dest: Ty<'tcx>,
) -> bool {
// Fast path.
if src == dest {
return true;
}
// Check for subtyping in either direction.
relate_types(tcx, param_env, Variance::Covariant, src, dest)
|| relate_types(tcx, param_env, Variance::Covariant, dest, src)
relate_types(tcx, typing_mode, param_env, Variance::Covariant, src, dest)
}
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
@ -35,6 +26,7 @@ pub fn is_equal_up_to_subtyping<'tcx>(
/// because we want to check for type equality.
pub fn relate_types<'tcx>(
tcx: TyCtxt<'tcx>,
typing_mode: TypingMode<'tcx>,
param_env: ParamEnv<'tcx>,
variance: Variance,
src: Ty<'tcx>,
@ -45,8 +37,7 @@ pub fn relate_types<'tcx>(
}
let mut builder = tcx.infer_ctxt().ignoring_regions();
// FIXME(#132279): This should eventually use the already defined hidden types.
let infcx = builder.build(TypingMode::from_param_env(param_env));
let infcx = builder.build(typing_mode);
let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy();
let src = ocx.normalize(&cause, param_env, src);

View File

@ -8,7 +8,7 @@ mod type_name;
pub use self::alignment::{is_disaligned, is_within_packed};
pub use self::check_validity_requirement::check_validity_requirement;
pub use self::compare_types::{is_equal_up_to_subtyping, relate_types};
pub use self::compare_types::{relate_types, sub_types};
pub use self::type_name::type_name;
/// Classify whether an operator is "left-homogeneous", i.e., the LHS has the

View File

@ -168,12 +168,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
match hir_bound {
hir::GenericBound::Trait(poly_trait_ref) => {
let hir::TraitBoundModifiers { constness, polarity } = poly_trait_ref.modifiers;
let polarity = match polarity {
rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
rustc_ast::BoundPolarity::Maybe(_) => continue,
};
let _ = self.lower_poly_trait_ref(
&poly_trait_ref.trait_ref,
poly_trait_ref.span,

View File

@ -51,7 +51,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
&trait_bound.trait_ref,
trait_bound.span,
hir::BoundConstness::Never,
ty::PredicatePolarity::Positive,
hir::BoundPolarity::Positive,
dummy_self,
&mut bounds,
PredicateFilter::SelfOnly,

View File

@ -668,7 +668,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
trait_ref: &hir::TraitRef<'tcx>,
span: Span,
constness: hir::BoundConstness,
polarity: ty::PredicatePolarity,
polarity: hir::BoundPolarity,
self_ty: Ty<'tcx>,
bounds: &mut Bounds<'tcx>,
predicate_filter: PredicateFilter,
@ -690,15 +690,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
Some(self_ty),
);
if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
&& !self.tcx().is_const_trait(trait_def_id)
{
self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
span,
modifier: constness.as_str(),
});
}
let tcx = self.tcx();
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
debug!(?bound_vars);
@ -708,6 +699,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
bound_vars,
);
let polarity = match polarity {
rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
rustc_ast::BoundPolarity::Maybe(_) => {
// Validate associated type at least. We may want to reject these
// outright in the future...
for constraint in trait_segment.args().constraints {
let _ = self.lower_assoc_item_constraint(
trait_ref.hir_ref_id,
poly_trait_ref,
constraint,
&mut Default::default(),
&mut Default::default(),
constraint.span,
predicate_filter,
);
}
return arg_count;
}
};
if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
&& !self.tcx().is_const_trait(trait_def_id)
{
self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
span,
modifier: constness.as_str(),
});
}
match predicate_filter {
PredicateFilter::All
| PredicateFilter::SelfOnly
@ -763,11 +784,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// since we should have emitted an error for them earlier, and they
// would not be well-formed!
if polarity != ty::PredicatePolarity::Positive {
assert!(
self.dcx().has_errors().is_some(),
self.dcx().span_delayed_bug(
constraint.span,
"negative trait bounds should not have assoc item constraints",
);
continue;
break;
}
// Specify type to assert that error was already reported in `Err` case.

View File

@ -5,9 +5,9 @@ edition = "2021"
[dependencies]
# tidy-alphabetical-start
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_hir = { path = "../rustc_hir" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
# tidy-alphabetical-end

View File

@ -9,6 +9,7 @@
use std::cell::Cell;
use std::vec;
use rustc_abi::ExternAbi;
use rustc_ast::util::parser::{self, AssocOp, Fixity};
use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
use rustc_ast_pretty::pp::{self, Breaks};
@ -20,7 +21,6 @@ use rustc_hir::{
use rustc_span::FileName;
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{Ident, Symbol, kw};
use rustc_target::spec::abi::Abi;
use {rustc_ast as ast, rustc_hir as hir};
pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: HirId) -> String {
@ -2240,7 +2240,7 @@ impl<'a> State<'a> {
fn print_ty_fn(
&mut self,
abi: Abi,
abi: ExternAbi,
safety: hir::Safety,
decl: &hir::FnDecl<'_>,
name: Option<Symbol>,
@ -2276,7 +2276,7 @@ impl<'a> State<'a> {
self.print_safety(header.safety);
if header.abi != Abi::Rust {
if header.abi != ExternAbi::Rust {
self.word_nbsp("extern");
self.word_nbsp(header.abi.to_string());
}

View File

@ -268,7 +268,7 @@ lint_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edi
lint_extern_without_abi = extern declarations without an explicit ABI are deprecated
.label = ABI should be specified here
.help = the default ABI is {$default_abi}
.suggestion = explicitly specify the {$default_abi} ABI
lint_for_loops_over_fallibles =
for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement

View File

@ -2738,11 +2738,9 @@ pub(crate) struct PatternsInFnsWithoutBodySub {
#[derive(LintDiagnostic)]
#[diag(lint_extern_without_abi)]
#[help]
pub(crate) struct MissingAbi {
#[label]
#[suggestion(code = "extern \"{default_abi}\"", applicability = "machine-applicable")]
pub span: Span,
pub default_abi: &'static str,
}

View File

@ -5,6 +5,7 @@ edition = "2021"
[dependencies]
# tidy-alphabetical-start
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_error_messages = { path = "../rustc_error_messages" }
@ -12,6 +13,5 @@ rustc_hir = { path = "../rustc_hir" }
rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
serde = { version = "1.0.125", features = ["derive"] }
# tidy-alphabetical-end

View File

@ -2,6 +2,7 @@
#![warn(unreachable_pub)]
// tidy-alphabetical-end
use rustc_abi::ExternAbi;
use rustc_ast::node_id::NodeId;
use rustc_ast::{AttrId, Attribute};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@ -15,7 +16,6 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
pub use rustc_span::edition::Edition;
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
use rustc_span::{Span, Symbol, sym};
use rustc_target::spec::abi::Abi;
use serde::{Deserialize, Serialize};
pub use self::Level::*;
@ -602,7 +602,7 @@ pub enum BuiltinLintDiag {
path: String,
since_kind: DeprecatedSinceKind,
},
MissingAbi(Span, Abi),
MissingAbi(Span, ExternAbi),
UnusedDocComment(Span),
UnusedBuiltinAttribute {
attr_name: Symbol,

View File

@ -39,7 +39,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths};
use crate::ty::visit::TypeVisitableExt;
use crate::ty::{
self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt,
self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingMode,
UserTypeAnnotationIndex,
};
@ -452,6 +452,15 @@ impl<'tcx> Body<'tcx> {
self.basic_blocks.as_mut()
}
pub fn typing_mode(&self, _tcx: TyCtxt<'tcx>) -> TypingMode<'tcx> {
match self.phase {
// FIXME(#132279): the MIR is quite clearly inside of a body, so we
// should instead reveal opaques defined by that body here.
MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(),
MirPhase::Runtime(_) => TypingMode::PostAnalysis,
}
}
#[inline]
pub fn local_kind(&self, local: Local) -> LocalKind {
let index = local.as_usize();

View File

@ -19,9 +19,8 @@ use smallvec::SmallVec;
use super::{BasicBlock, Const, Local, UserTypeProjection};
use crate::mir::coverage::CoverageKind;
use crate::traits::Reveal;
use crate::ty::adjustment::PointerCoercion;
use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex};
use crate::ty::{self, GenericArgsRef, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex};
/// Represents the "flavors" of MIR.
///
@ -102,10 +101,10 @@ impl MirPhase {
}
}
pub fn reveal(&self) -> Reveal {
match *self {
MirPhase::Built | MirPhase::Analysis(_) => Reveal::UserFacing,
MirPhase::Runtime(_) => Reveal::All,
pub fn param_env<'tcx>(&self, tcx: TyCtxt<'tcx>, body_def_id: DefId) -> ty::ParamEnv<'tcx> {
match self {
MirPhase::Built | MirPhase::Analysis(_) => tcx.param_env(body_def_id),
MirPhase::Runtime(_) => tcx.param_env_reveal_all_normalized(body_def_id),
}
}
}

View File

@ -7,6 +7,8 @@ edition = "2021"
# tidy-alphabetical-start
either = "1.5.0"
itertools = "0.12"
rustc_abi = { path = "../rustc_abi" }
rustc_apfloat = "0.2.0"
rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
@ -22,7 +24,6 @@ rustc_middle = { path = "../rustc_middle" }
rustc_pattern_analysis = { path = "../rustc_pattern_analysis" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
tracing = "0.1"
# tidy-alphabetical-end

View File

@ -1,3 +1,4 @@
use rustc_abi::{FieldIdx, VariantIdx};
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::*;
@ -6,7 +7,6 @@ use rustc_middle::ty;
use rustc_middle::ty::cast::mir_cast_kind;
use rustc_span::Span;
use rustc_span::source_map::Spanned;
use rustc_target::abi::{FieldIdx, VariantIdx};
use super::{PResult, ParseCtxt, parse_by_kind};
use crate::build::custom::ParseError;

View File

@ -1,5 +1,6 @@
//! See docs in build/expr/mod.rs
use rustc_abi::Size;
use rustc_ast as ast;
use rustc_hir::LangItem;
use rustc_middle::mir::interpret::{
@ -11,7 +12,6 @@ use rustc_middle::ty::{
self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, UserTypeAnnotationIndex,
};
use rustc_middle::{bug, mir, span_bug};
use rustc_target::abi::Size;
use tracing::{instrument, trace};
use crate::build::{Builder, parse_float_into_constval};

View File

@ -3,6 +3,7 @@
use std::assert_matches::assert_matches;
use std::iter;
use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
use rustc_hir::def_id::LocalDefId;
use rustc_middle::hir::place::{Projection as HirProjection, ProjectionKind as HirProjectionKind};
use rustc_middle::middle::region;
@ -12,7 +13,6 @@ use rustc_middle::thir::*;
use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
use rustc_middle::{bug, span_bug};
use rustc_span::Span;
use rustc_target::abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
use tracing::{debug, instrument, trace};
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};

View File

@ -1,5 +1,6 @@
//! See docs in `build/expr/mod.rs`.
use rustc_abi::{BackendRepr, FieldIdx, Primitive};
use rustc_hir::lang_items::LangItem;
use rustc_index::{Idx, IndexVec};
use rustc_middle::bug;
@ -13,7 +14,6 @@ use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, Ty, UpvarArgs};
use rustc_span::source_map::Spanned;
use rustc_span::{DUMMY_SP, Span};
use rustc_target::abi::{BackendRepr, FieldIdx, Primitive};
use tracing::debug;
use crate::build::expr::as_place::PlaceBase;

View File

@ -5,6 +5,7 @@
//! This also includes code for pattern bindings in `let` statements and
//! function parameters.
use rustc_abi::VariantIdx;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::{BindingMode, ByRef};
@ -15,7 +16,6 @@ use rustc_middle::thir::{self, *};
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
use rustc_span::symbol::Symbol;
use rustc_span::{BytePos, Pos, Span};
use rustc_target::abi::VariantIdx;
use tracing::{debug, instrument};
use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard};

View File

@ -1,4 +1,5 @@
use itertools::Itertools;
use rustc_abi::{ExternAbi, FieldIdx};
use rustc_apfloat::Float;
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
use rustc_ast::attr;
@ -20,8 +21,6 @@ use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt, TypeVisitableExt, TypingMode
use rustc_middle::{bug, span_bug};
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
use rustc_target::abi::FieldIdx;
use rustc_target::spec::abi::Abi;
use super::lints;
use crate::build::expr::as_place::PlaceBuilder;
@ -467,7 +466,7 @@ fn construct_fn<'tcx>(
if let DefKind::Closure = tcx.def_kind(fn_def) {
// HACK(eddyb) Avoid having RustCall on closures,
// as it adds unnecessary (and wrong) auto-tupling.
abi = Abi::Rust;
abi = ExternAbi::Rust;
}
let arguments = &thir.params;
@ -540,7 +539,7 @@ fn construct_fn<'tcx>(
let mut body = builder.finish();
body.spread_arg = if abi == Abi::RustCall {
body.spread_arg = if abi == ExternAbi::RustCall {
// RustCall pseudo-ABI untuples the last argument.
Some(Local::new(arguments.len()))
} else {

View File

@ -1,4 +1,5 @@
use itertools::Itertools;
use rustc_abi::{FIRST_VARIANT, FieldIdx};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@ -18,7 +19,6 @@ use rustc_middle::ty::{
};
use rustc_middle::{bug, span_bug};
use rustc_span::{Span, sym};
use rustc_target::abi::{FIRST_VARIANT, FieldIdx};
use tracing::{debug, info, instrument, trace};
use crate::errors;

View File

@ -1,4 +1,5 @@
use either::Either;
use rustc_abi::{FieldIdx, VariantIdx};
use rustc_apfloat::Float;
use rustc_hir as hir;
use rustc_index::Idx;
@ -9,7 +10,6 @@ use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::thir::{FieldPat, Pat, PatKind};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode, ValTree};
use rustc_span::Span;
use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_trait_selection::traits::ObligationCause;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use tracing::{debug, instrument, trace};

View File

@ -5,6 +5,7 @@ mod const_to_pat;
use std::cmp::Ordering;
use rustc_abi::{FieldIdx, Integer};
use rustc_errors::codes::*;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
@ -20,7 +21,6 @@ use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisita
use rustc_middle::{bug, span_bug};
use rustc_span::def_id::LocalDefId;
use rustc_span::{ErrorGuaranteed, Span};
use rustc_target::abi::{FieldIdx, Integer};
use tracing::{debug, instrument};
pub(crate) use self::check_match::check_match;

View File

@ -244,8 +244,13 @@ impl<'tcx> Inliner<'tcx> {
// Normally, this shouldn't be required, but trait normalization failure can create a
// validation ICE.
let output_type = callee_body.return_ty();
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, output_type, destination_ty)
{
if !util::sub_types(
self.tcx,
caller_body.typing_mode(self.tcx),
self.param_env,
output_type,
destination_ty,
) {
trace!(?output_type, ?destination_ty);
return Err("failed to normalize return type");
}
@ -275,8 +280,13 @@ impl<'tcx> Inliner<'tcx> {
self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
{
let input_type = callee_body.local_decls[input].ty;
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty)
{
if !util::sub_types(
self.tcx,
caller_body.typing_mode(self.tcx),
self.param_env,
input_type,
arg_ty,
) {
trace!(?arg_ty, ?input_type);
return Err("failed to normalize tuple argument type");
}
@ -285,8 +295,13 @@ impl<'tcx> Inliner<'tcx> {
for (arg, input) in args.iter().zip(callee_body.args_iter()) {
let input_type = callee_body.local_decls[input].ty;
let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx);
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty)
{
if !util::sub_types(
self.tcx,
caller_body.typing_mode(self.tcx),
self.param_env,
input_type,
arg_ty,
) {
trace!(?arg_ty, ?input_type);
return Err("failed to normalize argument type");
}

View File

@ -5,14 +5,14 @@ use rustc_hir::LangItem;
use rustc_index::IndexVec;
use rustc_index::bit_set::BitSet;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{Obligation, ObligationCause, Reveal};
use rustc_infer::traits::{Obligation, ObligationCause};
use rustc_middle::mir::coverage::CoverageKind;
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{
self, CoroutineArgsExt, InstanceKind, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt,
TypingMode, Variance,
Variance,
};
use rustc_middle::{bug, span_bug};
use rustc_target::abi::{FIRST_VARIANT, Size};
@ -20,7 +20,7 @@ use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::ObligationCtxt;
use rustc_type_ir::Upcast;
use crate::util::{is_within_packed, relate_types};
use crate::util::{self, is_within_packed};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum EdgeKind {
@ -50,11 +50,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator {
}
let def_id = body.source.def_id();
let mir_phase = self.mir_phase;
let param_env = match mir_phase.reveal() {
Reveal::UserFacing => tcx.param_env(def_id),
Reveal::All => tcx.param_env_reveal_all_normalized(def_id),
};
let param_env = mir_phase.param_env(tcx, def_id);
let can_unwind = if mir_phase <= MirPhase::Runtime(RuntimePhase::Initial) {
// In this case `AbortUnwindingCalls` haven't yet been executed.
true
@ -587,7 +583,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Variance::Covariant
};
crate::util::relate_types(self.tcx, self.param_env, variance, src, dest)
crate::util::relate_types(
self.tcx,
self.body.typing_mode(self.tcx),
self.param_env,
variance,
src,
dest,
)
}
/// Check that the given predicate definitely holds in the param-env of this MIR body.
@ -606,7 +609,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
return true;
}
let infcx = self.tcx.infer_ctxt().build(TypingMode::from_param_env(self.param_env));
let infcx = self.tcx.infer_ctxt().build(self.body.typing_mode(self.tcx));
let ocx = ObligationCtxt::new(&infcx);
ocx.register_obligation(Obligation::new(
self.tcx,
@ -798,10 +801,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
ProjectionElem::Subtype(ty) => {
if !relate_types(
if !util::sub_types(
self.tcx,
self.body.typing_mode(self.tcx),
self.param_env,
Variance::Covariant,
ty,
place_ref.ty(&self.body.local_decls, self.tcx).ty,
) {

View File

@ -1194,6 +1194,7 @@ impl<'a> Parser<'a> {
attrs: &mut AttrVec,
mut safety: Safety,
) -> PResult<'a, ItemInfo> {
let extern_span = self.prev_token.uninterpolated_span();
let abi = self.parse_abi(); // ABI?
// FIXME: This recovery should be tested better.
if safety == Safety::Default
@ -1205,6 +1206,7 @@ impl<'a> Parser<'a> {
let _ = self.eat_keyword(kw::Unsafe);
}
let module = ast::ForeignMod {
extern_span,
safety,
abi,
items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,

View File

@ -55,9 +55,15 @@ use crate::json::{Json, ToJson};
use crate::spec::abi::Abi;
use crate::spec::crt_objects::CrtObjects;
pub mod abi;
pub mod crt_objects;
pub mod abi {
pub use rustc_abi::{
AbiDisabled, AbiUnsupported, ExternAbi as Abi, all_names, enabled_names, is_enabled,
is_stable, lookup,
};
}
mod base;
pub use base::apple::{
deployment_target_for_target as current_apple_deployment_target,

View File

@ -14,8 +14,11 @@ pub(crate) fn target() -> Target {
arch: "mips".into(),
options: TargetOptions {
os: "none".into(),
env: "psx".into(),
// The Playstation 1 is mostly bare-metal, but the BIOS does provide some a slight bit
// of functionality post load, so we still declare it as `cfg!(target_os = "psx")`.
//
// See <https://github.com/rust-lang/rust/pull/131168> for details.
os: "psx".into(),
vendor: "sony".into(),
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
cpu: "mips1".into(),

View File

@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
std: Some(true),
},
pointer_width: 64,
data_layout: "E-m:e-i64:64-n32:64-S128".into(),
data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(),
arch: "sparc64".into(),
options: base,
}

View File

@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
std: Some(true),
},
pointer_width: 64,
data_layout: "E-m:e-i64:64-n32:64-S128".into(),
data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(),
arch: "sparc64".into(),
options: TargetOptions { endian: Endian::Big, mcount: "__mcount".into(), ..base },
}

View File

@ -17,7 +17,7 @@ pub(crate) fn target() -> Target {
std: Some(true),
},
pointer_width: 64,
data_layout: "E-m:e-i64:64-n32:64-S128".into(),
data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(),
arch: "sparc64".into(),
options: base,
}

View File

@ -11,7 +11,7 @@ pub(crate) fn target() -> Target {
std: Some(true),
},
pointer_width: 32,
data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(),
data_layout: "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64".into(),
arch: "sparc".into(),
options: TargetOptions {
cpu: "v9".into(),

View File

@ -17,7 +17,7 @@ pub(crate) fn target() -> Target {
..Default::default()
};
Target {
data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(),
data_layout: "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64".into(),
llvm_target: "sparc-unknown-none-elf".into(),
metadata: crate::spec::TargetMetadata {
description: Some("Bare 32-bit SPARC V7+".into()),

View File

@ -19,7 +19,7 @@ pub(crate) fn target() -> Target {
std: Some(true),
},
pointer_width: 64,
data_layout: "E-m:e-i64:64-n32:64-S128".into(),
data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(),
// Use "sparc64" instead of "sparcv9" here, since the former is already
// used widely in the source base. If we ever needed ABI
// differentiation from the sparc64, we could, but that would probably

View File

@ -411,7 +411,7 @@ pub fn normalize_param_env_or_error<'tcx>(
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal());
if !normalize::needs_normalization(&elaborated_env, unnormalized_env.reveal()) {
if !elaborated_env.has_aliases() {
return elaborated_env;
}

View File

@ -1,15 +1,16 @@
//! Deeply normalize types using the old trait solver.
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_infer::infer::InferOk;
use rustc_infer::infer::at::At;
use rustc_infer::infer::{InferCtxt, InferOk};
use rustc_infer::traits::{
FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine,
};
use rustc_macros::extension;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal};
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt,
TypingMode,
};
use tracing::{debug, instrument};
@ -109,16 +110,19 @@ where
}
pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
infcx: &InferCtxt<'tcx>,
param_env_for_debug_assertion: ty::ParamEnv<'tcx>,
value: &T,
reveal: Reveal,
) -> bool {
let mut flags = ty::TypeFlags::HAS_ALIAS;
// Opaques are treated as rigid with `Reveal::UserFacing`,
// so we can ignore those.
match reveal {
Reveal::UserFacing => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE),
Reveal::All => {}
match infcx.typing_mode(param_env_for_debug_assertion) {
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
flags.remove(ty::TypeFlags::HAS_TY_OPAQUE)
}
TypingMode::PostAnalysis => {}
}
value.has_type_flags(flags)
@ -154,7 +158,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
"Normalizing {value:?} without wrapping in a `Binder`"
);
if !needs_normalization(&value, self.param_env.reveal()) {
if !needs_normalization(self.selcx.infcx, self.param_env, &value) {
value
} else {
value.fold_with(self)
@ -178,7 +182,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if !needs_normalization(&ty, self.param_env.reveal()) {
if !needs_normalization(self.selcx.infcx, self.param_env, &ty) {
return ty;
}
@ -213,10 +217,11 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
match kind {
ty::Opaque => {
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty.super_fold_with(self),
Reveal::All => {
match self.selcx.infcx.typing_mode(self.param_env) {
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
ty.super_fold_with(self)
}
TypingMode::PostAnalysis => {
let recursion_limit = self.cx().recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
self.selcx.infcx.err_ctxt().report_overflow_error(
@ -403,7 +408,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
let tcx = self.selcx.tcx();
if tcx.features().generic_const_exprs()
|| !needs_normalization(&constant, self.param_env.reveal())
|| !needs_normalization(self.selcx.infcx, self.param_env, &constant)
{
constant
} else {
@ -420,7 +425,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
#[inline]
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) {
if p.allow_normalization() && needs_normalization(self.selcx.infcx, self.param_env, &p) {
p.super_fold_with(self)
} else {
p

View File

@ -16,7 +16,7 @@ use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedD
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
use rustc_middle::ty::{self, Term, Ty, TyCtxt, Upcast};
use rustc_middle::ty::{self, Term, Ty, TyCtxt, TypingMode, Upcast};
use rustc_middle::{bug, span_bug};
use rustc_span::symbol::sym;
use tracing::{debug, instrument};
@ -975,18 +975,21 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// and the obligation is monomorphic, otherwise passes such as
// transmute checking and polymorphic MIR optimizations could
// get a result which isn't correct for all monomorphizations.
if obligation.param_env.reveal() == Reveal::All {
// NOTE(eddyb) inference variables can resolve to parameters, so
// assume `poly_trait_ref` isn't monomorphic, if it contains any.
let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref);
!poly_trait_ref.still_further_specializable()
} else {
debug!(
assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
?obligation.predicate,
"assemble_candidates_from_impls: not eligible due to default",
);
false
match selcx.infcx.typing_mode(obligation.param_env) {
TypingMode::Coherence | TypingMode::Analysis { .. } => {
debug!(
assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
?obligation.predicate,
"assemble_candidates_from_impls: not eligible due to default",
);
false
}
TypingMode::PostAnalysis => {
// NOTE(eddyb) inference variables can resolve to parameters, so
// assume `poly_trait_ref` isn't monomorphic, if it contains any.
let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref);
!poly_trait_ref.still_further_specializable()
}
}
}
}

View File

@ -9,7 +9,7 @@ use rustc_macros::extension;
pub use rustc_middle::traits::query::NormalizationResult;
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor, TypingMode};
use rustc_span::DUMMY_SP;
use tracing::{debug, info, instrument};
@ -21,7 +21,7 @@ use crate::infer::canonical::OriginalQueryValues;
use crate::infer::{InferCtxt, InferOk};
use crate::traits::normalize::needs_normalization;
use crate::traits::{
BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, Reveal, ScrubbedTraitError,
BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, ScrubbedTraitError,
};
#[extension(pub trait QueryNormalizeExt<'tcx>)]
@ -89,7 +89,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
}
}
if !needs_normalization(&value, self.param_env.reveal()) {
if !needs_normalization(self.infcx, self.param_env, &value) {
return Ok(Normalized { value, obligations: PredicateObligations::new() });
}
@ -191,7 +191,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
if !needs_normalization(&ty, self.param_env.reveal()) {
if !needs_normalization(self.infcx, self.param_env, &ty) {
return Ok(ty);
}
@ -215,10 +215,12 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
let res = match kind {
ty::Opaque => {
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty.try_super_fold_with(self)?,
match self.infcx.typing_mode(self.param_env) {
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
ty.try_super_fold_with(self)?
}
Reveal::All => {
TypingMode::PostAnalysis => {
let args = data.args.try_fold_with(self)?;
let recursion_limit = self.cx().recursion_limit();
@ -332,7 +334,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
&mut self,
constant: ty::Const<'tcx>,
) -> Result<ty::Const<'tcx>, Self::Error> {
if !needs_normalization(&constant, self.param_env.reveal()) {
if !needs_normalization(self.infcx, self.param_env, &constant) {
return Ok(constant);
}
@ -351,7 +353,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
&mut self,
p: ty::Predicate<'tcx>,
) -> Result<ty::Predicate<'tcx>, Self::Error> {
if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) {
if p.allow_normalization() && needs_normalization(self.infcx, self.param_env, &p) {
p.try_super_fold_with(self)
} else {
Ok(p)

View File

@ -12,6 +12,13 @@ use crate::{self as ty, Interner};
/// The current typing mode of an inference context. We unfortunately have some
/// slightly different typing rules depending on the current context. See the
/// doc comment for each variant for how and why they are used.
///
/// In most cases you can get the correct typing mode automically via:
/// - `mir::Body::typing_mode`
/// - `rustc_lint::LateContext::typing_mode`
///
/// If neither of these functions are available, feel free to reach out to
/// t-types for help.
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
pub enum TypingMode<I: Interner> {

View File

@ -35,7 +35,7 @@ PICK_REFS=()
# commit hash of fuchsia.git and some other repos in the "monorepo" checkout, in
# addition to versions of prebuilts. It should be bumped regularly by the
# Fuchsia team  we aim for every 1-2 months.
INTEGRATION_SHA=1c5b42266fbfefb2337c6b2f0030a91bde15f9e9
INTEGRATION_SHA=9f632bb7446d5a6af2998f1a0ebdb4b8ea2f4511
checkout=fuchsia
jiri=.jiri_root/bin/jiri

View File

@ -52,5 +52,10 @@ Cross-compilation of these targets are supported using Clang, but may require
Xcode or the macOS SDK (`MacOSX.sdk`) to be available to compile C code and
to link.
The Clang target is suffixed with `-macosx`. Clang's `-darwin` target refers
to Darwin platforms in general (macOS/iOS/tvOS/watchOS/visionOS), and requires
the `-mmacosx-version-min=...`, `-miphoneos-version-min=...` or similar flags
to disambiguate.
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
environment variable.

View File

@ -17,7 +17,7 @@ use rustc_middle::mir::{
};
use rustc_middle::traits::{BuiltinImplSource, ImplSource, ObligationCause};
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt, TypingMode};
use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt};
use rustc_span::Span;
use rustc_span::symbol::sym;
use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext};
@ -420,7 +420,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]),
);
let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(obligation.param_env));
let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx));
let mut selcx = SelectionContext::new(&infcx);
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
return false;

View File

@ -362,7 +362,7 @@ fn is_normalizable_helper<'tcx>(
}
// prevent recursive loops, false-negative is better than endless loop leading to stack overflow
cache.insert(ty, false);
let infcx = cx.tcx.infer_ctxt().build(TypingMode::from_param_env(param_env));
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
let cause = ObligationCause::dummy();
let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() {
match ty.kind() {

View File

@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | target_env = "_UNEXPECTED_VALUE",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `psx`, `relibc`, `sgx`, and `uclibc`
= note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@ -210,7 +210,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | target_os = "_UNEXPECTED_VALUE",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@ -294,7 +294,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
| |
| help: there is a expected value with a similar name: `"linux"`
|
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: 30 warnings emitted

View File

@ -3,8 +3,6 @@
fn polarity() -> impl Sized + ?use<> {}
//~^ ERROR expected identifier, found keyword `use`
//~| ERROR cannot find trait `r#use` in this scope
//~| WARN relaxing a default bound only does something for `?Sized`
//~| WARN relaxing a default bound only does something for `?Sized`
fn asyncness() -> impl Sized + async use<> {}
//~^ ERROR expected identifier, found keyword `use`

View File

@ -5,19 +5,19 @@ LL | fn polarity() -> impl Sized + ?use<> {}
| ^^^ expected identifier, found keyword
error: expected identifier, found keyword `use`
--> $DIR/bound-modifiers.rs:9:38
--> $DIR/bound-modifiers.rs:7:38
|
LL | fn asyncness() -> impl Sized + async use<> {}
| ^^^ expected identifier, found keyword
error: expected identifier, found keyword `use`
--> $DIR/bound-modifiers.rs:14:38
--> $DIR/bound-modifiers.rs:12:38
|
LL | fn constness() -> impl Sized + const use<> {}
| ^^^ expected identifier, found keyword
error: expected identifier, found keyword `use`
--> $DIR/bound-modifiers.rs:19:37
--> $DIR/bound-modifiers.rs:17:37
|
LL | fn binder() -> impl Sized + for<'a> use<> {}
| ^^^ expected identifier, found keyword
@ -29,25 +29,25 @@ LL | fn polarity() -> impl Sized + ?use<> {}
| ^^^ not found in this scope
error[E0405]: cannot find trait `r#use` in this scope
--> $DIR/bound-modifiers.rs:9:38
--> $DIR/bound-modifiers.rs:7:38
|
LL | fn asyncness() -> impl Sized + async use<> {}
| ^^^ not found in this scope
error[E0405]: cannot find trait `r#use` in this scope
--> $DIR/bound-modifiers.rs:14:38
--> $DIR/bound-modifiers.rs:12:38
|
LL | fn constness() -> impl Sized + const use<> {}
| ^^^ not found in this scope
error[E0405]: cannot find trait `r#use` in this scope
--> $DIR/bound-modifiers.rs:19:37
--> $DIR/bound-modifiers.rs:17:37
|
LL | fn binder() -> impl Sized + for<'a> use<> {}
| ^^^ not found in this scope
error[E0658]: async closures are unstable
--> $DIR/bound-modifiers.rs:9:32
--> $DIR/bound-modifiers.rs:7:32
|
LL | fn asyncness() -> impl Sized + async use<> {}
| ^^^^^
@ -58,7 +58,7 @@ LL | fn asyncness() -> impl Sized + async use<> {}
= help: to use an async block, remove the `||`: `async {`
error[E0658]: const trait impls are experimental
--> $DIR/bound-modifiers.rs:14:32
--> $DIR/bound-modifiers.rs:12:32
|
LL | fn constness() -> impl Sized + const use<> {}
| ^^^^^
@ -67,21 +67,7 @@ LL | fn constness() -> impl Sized + const use<> {}
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/bound-modifiers.rs:3:31
|
LL | fn polarity() -> impl Sized + ?use<> {}
| ^^^^^^
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/bound-modifiers.rs:3:31
|
LL | fn polarity() -> impl Sized + ?use<> {}
| ^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 10 previous errors; 2 warnings emitted
error: aborting due to 10 previous errors
Some errors have detailed explanations: E0405, E0658.
For more information about an error, try `rustc --explain E0405`.

View File

@ -1,6 +1,5 @@
struct Foo<T: ?Hash> {}
//~^ ERROR expected trait, found derive macro `Hash`
//~^^ ERROR parameter `T` is never used
//~^^^ WARN relaxing a default bound only does something for `?Sized`
//~| WARN relaxing a default bound only does something for `?Sized`
fn main() {}

View File

@ -15,15 +15,6 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr
LL | struct Foo<T: ?Hash> {}
| ^^^^^
error[E0392]: type parameter `T` is never used
--> $DIR/issue-37534.rs:1:12
|
LL | struct Foo<T: ?Hash> {}
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
error: aborting due to 1 previous error; 1 warning emitted
error: aborting due to 2 previous errors; 1 warning emitted
Some errors have detailed explanations: E0392, E0404.
For more information about an error, try `rustc --explain E0392`.
For more information about this error, try `rustc --explain E0404`.

View File

@ -2,9 +2,8 @@ error: extern declarations without an explicit ABI are deprecated
--> $DIR/cli-lint-override.rs:12:1
|
LL | extern fn foo() {}
| ^^^^^^^^^^^^^^^ ABI should be specified here
| ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
|
= help: the default ABI is C
= note: requested on the command line with `-F missing-abi`
error: aborting due to 1 previous error

View File

@ -2,9 +2,8 @@ warning: extern declarations without an explicit ABI are deprecated
--> $DIR/cli-lint-override.rs:12:1
|
LL | extern fn foo() {}
| ^^^^^^^^^^^^^^^ ABI should be specified here
| ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
|
= help: the default ABI is C
= note: requested on the command line with `--force-warn missing-abi`
warning: 1 warning emitted

View File

@ -2,9 +2,8 @@ error: extern declarations without an explicit ABI are deprecated
--> $DIR/cli-lint-override.rs:12:1
|
LL | extern fn foo() {}
| ^^^^^^^^^^^^^^^ ABI should be specified here
| ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
|
= help: the default ABI is C
= note: requested on the command line with `-D missing-abi`
error: aborting due to 1 previous error

View File

@ -0,0 +1,4 @@
fn uwu<T: ?Sized<i32>>() {}
//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
fn main() {}

View File

@ -0,0 +1,11 @@
error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/maybe-bound-generics-deny.rs:1:12
|
LL | fn uwu<T: ?Sized<i32>>() {}
| ^^^^^----- help: remove the unnecessary generics
| |
| expected 0 generic arguments
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0107`.

View File

@ -0,0 +1,7 @@
trait Trait {}
fn test<T: ?self::<i32>::Trait>() {}
//~^ ERROR type arguments are not allowed on this type
//~| WARN relaxing a default bound only does something for `?Sized`
fn main() {}

View File

@ -0,0 +1,17 @@
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bound-has-path-args.rs:3:12
|
LL | fn test<T: ?self::<i32>::Trait>() {}
| ^^^^^^^^^^^^^^^^^^^
error[E0109]: type arguments are not allowed on this type
--> $DIR/maybe-bound-has-path-args.rs:3:20
|
LL | fn test<T: ?self::<i32>::Trait>() {}
| ---- ^^^ type argument not allowed
| |
| not allowed on this type
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0109`.

View File

@ -0,0 +1,12 @@
trait HasAssoc {
type Assoc;
}
fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
//~^ WARN relaxing a default bound
trait NoAssoc {}
fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
//~^ WARN relaxing a default bound
//~| ERROR associated type `Missing` not found for `NoAssoc`
fn main() {}

View File

@ -0,0 +1,21 @@
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bound-with-assoc.rs:4:16
|
LL | fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
| ^^^^^^^^^^^^^^^^^^^^^
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bound-with-assoc.rs:8:15
|
LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0220]: associated type `Missing` not found for `NoAssoc`
--> $DIR/maybe-bound-with-assoc.rs:8:24
|
LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
| ^^^^^^^ associated type `Missing` not found
error: aborting due to 1 previous error; 2 warnings emitted
For more information about this error, try `rustc --explain E0220`.