mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Auto merge of #109253 - matthiaskrgr:rollup-2xmv5zk, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #108958 (Remove box expressions from HIR) - #109044 (Prevent stable `libtest` from supporting `-Zunstable-options`) - #109155 (Fix riscv64 fuchsia LLVM target name) - #109156 (Fix linker detection for clang with prefix) - #109181 (inherit_overflow: adapt pattern to also work with v0 mangling) - #109198 (Install projection from RPITIT to default trait method opaque correctly) - #109215 (Use sort_by_key instead of sort_by) - #109229 (Fix invalid markdown link references) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
03b01c5bec
@ -259,7 +259,6 @@ pub enum ExprPrecedence {
|
||||
Assign,
|
||||
AssignOp,
|
||||
|
||||
Box,
|
||||
AddrOf,
|
||||
Let,
|
||||
Unary,
|
||||
@ -319,8 +318,7 @@ impl ExprPrecedence {
|
||||
ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8,
|
||||
|
||||
// Unary, prefix
|
||||
ExprPrecedence::Box
|
||||
| ExprPrecedence::AddrOf
|
||||
ExprPrecedence::AddrOf
|
||||
// Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
|
||||
// However, this is not exactly right. When `let _ = a` is the LHS of a binop we
|
||||
// need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
|
||||
|
@ -255,7 +255,7 @@ fn sccs_info<'cx, 'tcx>(
|
||||
let var_to_origin = infcx.reg_var_to_origin.borrow();
|
||||
|
||||
let mut var_to_origin_sorted = var_to_origin.clone().into_iter().collect::<Vec<_>>();
|
||||
var_to_origin_sorted.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
var_to_origin_sorted.sort_by_key(|vto| vto.0);
|
||||
let mut debug_str = "region variables to origins:\n".to_string();
|
||||
for (reg_var, origin) in var_to_origin_sorted.into_iter() {
|
||||
debug_str.push_str(&format!("{:?}: {:?}\n", reg_var, origin));
|
||||
@ -2216,7 +2216,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
// is in the same SCC or something. In that case, find what
|
||||
// appears to be the most interesting point to report to the
|
||||
// user via an even more ad-hoc guess.
|
||||
categorized_path.sort_by(|p0, p1| p0.category.cmp(&p1.category));
|
||||
categorized_path.sort_by_key(|p| p.category);
|
||||
debug!("sorted_path={:#?}", categorized_path);
|
||||
|
||||
(categorized_path.remove(0), extra_info)
|
||||
|
@ -1199,7 +1199,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|
||||
.and_then(|(lhs, rhs)| rhs.chars().all(char::is_numeric).then_some(lhs))
|
||||
.unwrap_or(stem);
|
||||
|
||||
// GCC can have an optional target prefix.
|
||||
// GCC/Clang can have an optional target prefix.
|
||||
let flavor = if stem == "emcc" {
|
||||
LinkerFlavor::EmCc
|
||||
} else if stem == "gcc"
|
||||
@ -1207,7 +1207,9 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|
||||
|| stem == "g++"
|
||||
|| stem.ends_with("-g++")
|
||||
|| stem == "clang"
|
||||
|| stem.ends_with("-clang")
|
||||
|| stem == "clang++"
|
||||
|| stem.ends_with("-clang++")
|
||||
{
|
||||
LinkerFlavor::from_cli(LinkerFlavorCli::Gcc, &sess.target)
|
||||
} else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") {
|
||||
|
@ -1673,7 +1673,6 @@ pub struct Expr<'hir> {
|
||||
impl Expr<'_> {
|
||||
pub fn precedence(&self) -> ExprPrecedence {
|
||||
match self.kind {
|
||||
ExprKind::Box(_) => ExprPrecedence::Box,
|
||||
ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
|
||||
ExprKind::Array(_) => ExprPrecedence::Array,
|
||||
ExprKind::Call(..) => ExprPrecedence::Call,
|
||||
@ -1763,7 +1762,6 @@ impl Expr<'_> {
|
||||
| ExprKind::Lit(_)
|
||||
| ExprKind::ConstBlock(..)
|
||||
| ExprKind::Unary(..)
|
||||
| ExprKind::Box(..)
|
||||
| ExprKind::AddrOf(..)
|
||||
| ExprKind::Binary(..)
|
||||
| ExprKind::Yield(..)
|
||||
@ -1851,7 +1849,6 @@ impl Expr<'_> {
|
||||
| ExprKind::InlineAsm(..)
|
||||
| ExprKind::AssignOp(..)
|
||||
| ExprKind::ConstBlock(..)
|
||||
| ExprKind::Box(..)
|
||||
| ExprKind::Binary(..)
|
||||
| ExprKind::Yield(..)
|
||||
| ExprKind::DropTemps(..)
|
||||
@ -1862,8 +1859,7 @@ impl Expr<'_> {
|
||||
/// To a first-order approximation, is this a pattern?
|
||||
pub fn is_approximately_pattern(&self) -> bool {
|
||||
match &self.kind {
|
||||
ExprKind::Box(_)
|
||||
| ExprKind::Array(_)
|
||||
ExprKind::Array(_)
|
||||
| ExprKind::Call(..)
|
||||
| ExprKind::Tup(_)
|
||||
| ExprKind::Lit(_)
|
||||
@ -1910,8 +1906,6 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
|
||||
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
pub enum ExprKind<'hir> {
|
||||
/// A `box x` expression.
|
||||
Box(&'hir Expr<'hir>),
|
||||
/// Allow anonymous constants from an inline `const` block
|
||||
ConstBlock(AnonConst),
|
||||
/// An array (e.g., `[a, b, c, d]`).
|
||||
|
@ -682,7 +682,6 @@ pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonCo
|
||||
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) {
|
||||
visitor.visit_id(expression.hir_id);
|
||||
match expression.kind {
|
||||
ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression),
|
||||
ExprKind::Array(subexpressions) => {
|
||||
walk_list!(visitor, visit_expr, subexpressions);
|
||||
}
|
||||
|
@ -557,7 +557,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
||||
check_opaque(tcx, id);
|
||||
}
|
||||
DefKind::ImplTraitPlaceholder => {
|
||||
let parent = tcx.impl_trait_in_trait_parent(id.owner_id.to_def_id());
|
||||
let parent = tcx.impl_trait_in_trait_parent_fn(id.owner_id.to_def_id());
|
||||
// Only check the validity of this opaque type if the function has a default body
|
||||
if let hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::autoderef::Autoderef;
|
||||
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
|
||||
|
||||
use hir::def::DefKind;
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
|
||||
@ -1548,16 +1547,27 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
|
||||
if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id())
|
||||
&& assoc_item.container == ty::AssocItemContainer::TraitContainer
|
||||
{
|
||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): Even with the new lowering
|
||||
// strategy, we can't just call `check_associated_item` on the new RPITITs,
|
||||
// because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail.
|
||||
// That's because we need to check that the bounds of the RPITIT hold using
|
||||
// the special substs that we create during opaque type lowering, otherwise we're
|
||||
// getting a bunch of early bound and free regions mixed up... Haven't looked too
|
||||
// deep into this, though.
|
||||
for arg in fn_output.walk() {
|
||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||
&& let ty::Alias(ty::Opaque, proj) = ty.kind()
|
||||
&& tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
|
||||
&& tcx.impl_trait_in_trait_parent(proj.def_id) == fn_def_id.to_def_id()
|
||||
// RPITITs are always eagerly normalized into opaques, so always look for an
|
||||
// opaque here.
|
||||
&& let ty::Alias(ty::Opaque, opaque_ty) = ty.kind()
|
||||
&& let Some(opaque_def_id) = opaque_ty.def_id.as_local()
|
||||
&& let opaque = tcx.hir().expect_item(opaque_def_id).expect_opaque_ty()
|
||||
&& let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = opaque.origin
|
||||
&& source == fn_def_id
|
||||
{
|
||||
let span = tcx.def_span(proj.def_id);
|
||||
let bounds = wfcx.tcx().explicit_item_bounds(proj.def_id);
|
||||
let span = tcx.def_span(opaque_ty.def_id);
|
||||
let bounds = wfcx.tcx().explicit_item_bounds(opaque_ty.def_id);
|
||||
let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
|
||||
let bound = ty::EarlyBinder(bound).subst(tcx, proj.substs);
|
||||
let bound = ty::EarlyBinder(bound).subst(tcx, opaque_ty.substs);
|
||||
let normalized_bound = wfcx.normalize(span, None, bound);
|
||||
traits::wf::predicate_obligations(
|
||||
wfcx.infcx,
|
||||
|
@ -3,7 +3,7 @@ use crate::astconv::AstConv;
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::util;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::{self, ImplTraitInTraitData, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::Span;
|
||||
|
||||
@ -76,18 +76,26 @@ pub(super) fn explicit_item_bounds(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> &'_ [(ty::Predicate<'_>, Span)] {
|
||||
// If the def_id is about an RPITIT, delegate explicit_item_bounds to the opaque_def_id that
|
||||
// generated the synthesized associate type.
|
||||
let rpitit_info = if let Some(ImplTraitInTraitData::Trait { opaque_def_id, .. }) =
|
||||
tcx.opt_rpitit_info(def_id)
|
||||
{
|
||||
Some(opaque_def_id)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
match tcx.opt_rpitit_info(def_id) {
|
||||
// RPITIT's bounds are the same as opaque type bounds, but with
|
||||
// a projection self type.
|
||||
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
|
||||
let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item();
|
||||
let opaque_ty = item.expect_opaque_ty();
|
||||
return opaque_type_bounds(
|
||||
tcx,
|
||||
opaque_def_id,
|
||||
opaque_ty.bounds,
|
||||
tcx.mk_projection(def_id, ty::InternalSubsts::identity_for_item(tcx, def_id)),
|
||||
item.span,
|
||||
);
|
||||
}
|
||||
// These should have been fed!
|
||||
Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(),
|
||||
None => {}
|
||||
}
|
||||
|
||||
let bounds_def_id = rpitit_info.unwrap_or(def_id);
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(bounds_def_id.expect_local());
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||
match tcx.hir().get(hir_id) {
|
||||
hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Type(bounds, _),
|
||||
@ -100,12 +108,12 @@ pub(super) fn explicit_item_bounds(
|
||||
..
|
||||
}) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let item_ty = if *in_trait || rpitit_info.is_some() {
|
||||
let item_ty = if *in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
tcx.mk_projection(def_id, substs)
|
||||
} else {
|
||||
tcx.mk_opaque(def_id, substs)
|
||||
};
|
||||
opaque_type_bounds(tcx, bounds_def_id, bounds, item_ty, *span)
|
||||
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
|
||||
}
|
||||
_ => bug!("item_bounds called on {:?}", def_id),
|
||||
}
|
||||
|
@ -112,10 +112,14 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match t.kind() {
|
||||
ty::Alias(_, ty::AliasTy { def_id, substs, .. })
|
||||
if matches!(
|
||||
self.tcx.def_kind(*def_id),
|
||||
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder
|
||||
) =>
|
||||
if matches!(self.tcx.def_kind(*def_id), DefKind::OpaqueTy) =>
|
||||
{
|
||||
self.visit_opaque(*def_id, substs)
|
||||
}
|
||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) check whether this is necessary
|
||||
// at all for RPITITs.
|
||||
ty::Alias(_, ty::AliasTy { def_id, substs, .. })
|
||||
if self.tcx.is_impl_trait_in_trait(*def_id) =>
|
||||
{
|
||||
self.visit_opaque(*def_id, substs)
|
||||
}
|
||||
|
@ -1366,10 +1366,6 @@ impl<'a> State<'a> {
|
||||
self.ibox(INDENT_UNIT);
|
||||
self.ann.pre(self, AnnNode::Expr(expr));
|
||||
match expr.kind {
|
||||
hir::ExprKind::Box(expr) => {
|
||||
self.word_space("Box::new");
|
||||
self.print_call_post(std::slice::from_ref(expr));
|
||||
}
|
||||
hir::ExprKind::Array(exprs) => {
|
||||
self.print_expr_vec(exprs);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
|
||||
|
||||
use hir::def::DefKind;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
@ -715,14 +714,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.subst_iter_copied(self.tcx, substs)
|
||||
.find_map(|(p, s)| get_future_output(p, s))?,
|
||||
ty::Error(_) => return None,
|
||||
ty::Alias(ty::Projection, proj)
|
||||
if self.tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder =>
|
||||
{
|
||||
self.tcx
|
||||
.bound_explicit_item_bounds(proj.def_id)
|
||||
.subst_iter_copied(self.tcx, proj.substs)
|
||||
.find_map(|(p, s)| get_future_output(p, s))?
|
||||
}
|
||||
ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => self
|
||||
.tcx
|
||||
.bound_explicit_item_bounds(proj.def_id)
|
||||
.subst_iter_copied(self.tcx, proj.substs)
|
||||
.find_map(|(p, s)| get_future_output(p, s))?,
|
||||
_ => span_bug!(
|
||||
self.tcx.def_span(expr_def_id),
|
||||
"async fn generator return type not an inference variable: {ret_ty}"
|
||||
|
@ -284,7 +284,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let tcx = self.tcx;
|
||||
match expr.kind {
|
||||
ExprKind::Box(subexpr) => self.check_expr_box(subexpr, expected),
|
||||
ExprKind::Lit(ref lit) => self.check_lit(&lit, expected),
|
||||
ExprKind::Binary(op, lhs, rhs) => self.check_binop(expr, op, lhs, rhs, expected),
|
||||
ExprKind::Assign(lhs, rhs, span) => {
|
||||
@ -359,16 +358,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr_box(&self, expr: &'tcx hir::Expr<'tcx>, expected: Expectation<'tcx>) -> Ty<'tcx> {
|
||||
let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| match ty.kind() {
|
||||
ty::Adt(def, _) if def.is_box() => Expectation::rvalue_hint(self, ty.boxed_ty()),
|
||||
_ => NoExpectation,
|
||||
});
|
||||
let referent_ty = self.check_expr_with_expectation(expr, expected_inner);
|
||||
self.require_type_is_sized(referent_ty, expr.span, traits::SizedBoxType);
|
||||
self.tcx.mk_box(referent_ty)
|
||||
}
|
||||
|
||||
fn check_expr_unary(
|
||||
&self,
|
||||
unop: hir::UnOp,
|
||||
|
@ -356,10 +356,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||
self.walk_captures(closure);
|
||||
}
|
||||
|
||||
hir::ExprKind::Box(ref base) => {
|
||||
self.consume_expr(base);
|
||||
}
|
||||
|
||||
hir::ExprKind::Yield(value, _) => {
|
||||
self.consume_expr(value);
|
||||
}
|
||||
|
@ -190,7 +190,6 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
|
||||
//
|
||||
// Some of these may be interesting in the future
|
||||
ExprKind::Path(..)
|
||||
| ExprKind::Box(..)
|
||||
| ExprKind::ConstBlock(..)
|
||||
| ExprKind::Array(..)
|
||||
| ExprKind::Call(..)
|
||||
@ -478,7 +477,6 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
|
||||
| ExprKind::AssignOp(..)
|
||||
| ExprKind::Binary(..)
|
||||
| ExprKind::Block(..)
|
||||
| ExprKind::Box(..)
|
||||
| ExprKind::Cast(..)
|
||||
| ExprKind::Closure { .. }
|
||||
| ExprKind::ConstBlock(..)
|
||||
|
@ -382,7 +382,6 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||
| hir::ExprKind::Struct(..)
|
||||
| hir::ExprKind::Repeat(..)
|
||||
| hir::ExprKind::InlineAsm(..)
|
||||
| hir::ExprKind::Box(..)
|
||||
| hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)),
|
||||
}
|
||||
}
|
||||
|
@ -359,10 +359,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
|
||||
let (def_id, substs) = match *ty.kind() {
|
||||
ty::Alias(_, ty::AliasTy { def_id, substs, .. })
|
||||
if matches!(
|
||||
self.tcx.def_kind(def_id),
|
||||
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder
|
||||
) =>
|
||||
if matches!(self.tcx.def_kind(def_id), DefKind::OpaqueTy) =>
|
||||
{
|
||||
(def_id, substs)
|
||||
}
|
||||
ty::Alias(_, ty::AliasTy { def_id, substs, .. })
|
||||
if self.tcx.is_impl_trait_in_trait(def_id) =>
|
||||
{
|
||||
(def_id, substs)
|
||||
}
|
||||
@ -1757,8 +1759,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
)
|
||||
}
|
||||
(true, ty::Alias(ty::Projection, proj))
|
||||
if self.tcx.def_kind(proj.def_id)
|
||||
== DefKind::ImplTraitPlaceholder =>
|
||||
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
|
||||
{
|
||||
let sm = self.tcx.sess.source_map();
|
||||
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::TypeErrCtxt;
|
||||
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
|
||||
use rustc_errors::{pluralize, Diagnostic, MultiSpan};
|
||||
use rustc_hir::{self as hir, def::DefKind};
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::traits::ObligationCauseCode;
|
||||
use rustc_middle::ty::error::ExpectedFound;
|
||||
use rustc_middle::ty::print::Printer;
|
||||
@ -75,7 +75,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
diag.note("an associated type was expected, but a different one was found");
|
||||
}
|
||||
(ty::Param(p), ty::Alias(ty::Projection, proj)) | (ty::Alias(ty::Projection, proj), ty::Param(p))
|
||||
if tcx.def_kind(proj.def_id) != DefKind::ImplTraitPlaceholder =>
|
||||
if !tcx.is_impl_trait_in_trait(proj.def_id) =>
|
||||
{
|
||||
let p_def_id = tcx
|
||||
.generics_of(body_owner_def_id)
|
||||
@ -222,7 +222,7 @@ impl<T> Trait<T> for X {
|
||||
diag.span_label(p_span, "this type parameter");
|
||||
}
|
||||
}
|
||||
(ty::Alias(ty::Projection, proj_ty), _) if tcx.def_kind(proj_ty.def_id) != DefKind::ImplTraitPlaceholder => {
|
||||
(ty::Alias(ty::Projection, proj_ty), _) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => {
|
||||
self.expected_projection(
|
||||
diag,
|
||||
proj_ty,
|
||||
@ -231,7 +231,7 @@ impl<T> Trait<T> for X {
|
||||
cause.code(),
|
||||
);
|
||||
}
|
||||
(_, ty::Alias(ty::Projection, proj_ty)) if tcx.def_kind(proj_ty.def_id) != DefKind::ImplTraitPlaceholder => {
|
||||
(_, ty::Alias(ty::Projection, proj_ty)) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => {
|
||||
let msg = format!(
|
||||
"consider constraining the associated type `{}` to `{}`",
|
||||
values.found, values.expected,
|
||||
|
@ -3,7 +3,6 @@ use super::{DefineOpaqueTypes, InferResult};
|
||||
use crate::errors::OpaqueHiddenTypeDiag;
|
||||
use crate::infer::{DefiningAnchor, InferCtxt, InferOk};
|
||||
use crate::traits;
|
||||
use hir::def::DefKind;
|
||||
use hir::def_id::{DefId, LocalDefId};
|
||||
use hir::OpaqueTyOrigin;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
@ -478,9 +477,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
ty::Alias(ty::Projection, proj)
|
||||
if self.tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder =>
|
||||
{
|
||||
ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => {
|
||||
// Skip lifetime parameters that are not captures.
|
||||
let variances = self.tcx.variances_of(proj.def_id);
|
||||
|
||||
@ -559,8 +556,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
// FIXME(RPITIT): Don't replace RPITITs with inference vars.
|
||||
ty::Alias(ty::Projection, projection_ty)
|
||||
if !projection_ty.has_escaping_bound_vars()
|
||||
&& tcx.def_kind(projection_ty.def_id)
|
||||
!= DefKind::ImplTraitPlaceholder =>
|
||||
&& !tcx.is_impl_trait_in_trait(projection_ty.def_id) =>
|
||||
{
|
||||
self.infer_projection(
|
||||
param_env,
|
||||
|
@ -1028,7 +1028,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
|
||||
| DefKind::InlineConst => true,
|
||||
|
||||
DefKind::ImplTraitPlaceholder => {
|
||||
let parent_def_id = tcx.impl_trait_in_trait_parent(def_id.to_def_id());
|
||||
let parent_def_id = tcx.impl_trait_in_trait_parent_fn(def_id.to_def_id());
|
||||
let assoc_item = tcx.associated_item(parent_def_id);
|
||||
match assoc_item.container {
|
||||
// Always encode an RPIT in an impl fn, since it always has a body
|
||||
|
@ -191,6 +191,7 @@ rustc_queries! {
|
||||
{
|
||||
desc { "determine whether the opaque is a type-alias impl trait" }
|
||||
separate_provide_extern
|
||||
feedable
|
||||
}
|
||||
|
||||
query unsizing_params_for_adt(key: DefId) -> &'tcx rustc_index::bit_set::BitSet<u32>
|
||||
|
@ -305,8 +305,6 @@ pub enum ObligationCauseCode<'tcx> {
|
||||
SizedReturnType,
|
||||
/// Yield type must be `Sized`.
|
||||
SizedYieldType,
|
||||
/// Box expression result type must be `Sized`.
|
||||
SizedBoxType,
|
||||
/// Inline asm operand type must be `Sized`.
|
||||
InlineAsmSized,
|
||||
/// `[expr; N]` requires `type_of(expr): Copy`.
|
||||
|
@ -2552,12 +2552,18 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait))
|
||||
}
|
||||
|
||||
pub fn impl_trait_in_trait_parent(self, mut def_id: DefId) -> DefId {
|
||||
while let def_kind = self.def_kind(def_id) && def_kind != DefKind::AssocFn {
|
||||
debug_assert_eq!(def_kind, DefKind::ImplTraitPlaceholder);
|
||||
def_id = self.parent(def_id);
|
||||
pub fn impl_trait_in_trait_parent_fn(self, mut def_id: DefId) -> DefId {
|
||||
match self.opt_rpitit_info(def_id) {
|
||||
Some(ImplTraitInTraitData::Trait { fn_def_id, .. })
|
||||
| Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) => fn_def_id,
|
||||
None => {
|
||||
while let def_kind = self.def_kind(def_id) && def_kind != DefKind::AssocFn {
|
||||
debug_assert_eq!(def_kind, DefKind::ImplTraitPlaceholder);
|
||||
def_id = self.parent(def_id);
|
||||
}
|
||||
def_id
|
||||
}
|
||||
}
|
||||
def_id
|
||||
}
|
||||
|
||||
pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
|
||||
@ -2572,6 +2578,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
let Some(trait_item_def_id) = item.trait_item_def_id else { return false; };
|
||||
|
||||
if self.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
return !self.associated_items_for_impl_trait_in_trait(trait_item_def_id).is_empty();
|
||||
}
|
||||
|
||||
// FIXME(RPITIT): This does a somewhat manual walk through the signature
|
||||
// of the trait fn to look for any RPITITs, but that's kinda doing a lot
|
||||
// of work. We can probably remove this when we refactor RPITITs to be
|
||||
|
@ -728,7 +728,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
}
|
||||
ty::Alias(ty::Projection, ref data) => {
|
||||
if !(self.should_print_verbose() || NO_QUERIES.with(|q| q.get()))
|
||||
&& self.tcx().def_kind(data.def_id) == DefKind::ImplTraitPlaceholder
|
||||
&& self.tcx().is_impl_trait_in_trait(data.def_id)
|
||||
{
|
||||
return self.pretty_print_opaque_impl_type(data.def_id, data.substs);
|
||||
} else {
|
||||
|
@ -1288,7 +1288,7 @@ impl<'tcx> AliasTy<'tcx> {
|
||||
match tcx.def_kind(self.def_id) {
|
||||
DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
|
||||
DefKind::ImplTraitPlaceholder => {
|
||||
tcx.parent(tcx.impl_trait_in_trait_parent(self.def_id))
|
||||
tcx.parent(tcx.impl_trait_in_trait_parent_fn(self.def_id))
|
||||
}
|
||||
kind => bug!("expected a projection AliasTy; found {kind:?}"),
|
||||
}
|
||||
|
@ -780,7 +780,6 @@ impl<'tcx> Cx<'tcx> {
|
||||
hir::ExprKind::DropTemps(ref source) => {
|
||||
ExprKind::Use { source: self.mirror_expr(source) }
|
||||
}
|
||||
hir::ExprKind::Box(ref value) => ExprKind::Box { value: self.mirror_expr(value) },
|
||||
hir::ExprKind::Array(ref fields) => {
|
||||
ExprKind::Array { fields: self.mirror_exprs(fields) }
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||
record_variants!(
|
||||
(self, e, e.kind, Id::Node(e.hir_id), hir, Expr, ExprKind),
|
||||
[
|
||||
Box, ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type,
|
||||
ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type,
|
||||
DropTemps, Let, If, Loop, Match, Closure, Block, Assign, AssignOp, Field, Index,
|
||||
Path, AddrOf, Break, Continue, Ret, InlineAsm, Struct, Repeat, Yield, Err
|
||||
]
|
||||
|
@ -473,7 +473,6 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
|
||||
| hir::ExprKind::Struct(..)
|
||||
| hir::ExprKind::Repeat(..)
|
||||
| hir::ExprKind::InlineAsm(..)
|
||||
| hir::ExprKind::Box(..)
|
||||
| hir::ExprKind::Type(..)
|
||||
| hir::ExprKind::Err(_)
|
||||
| hir::ExprKind::Path(hir::QPath::TypeRelative(..))
|
||||
@ -1059,8 +1058,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
self.propagate_through_expr(&l, r_succ)
|
||||
}
|
||||
|
||||
hir::ExprKind::Box(ref e)
|
||||
| hir::ExprKind::AddrOf(_, _, ref e)
|
||||
hir::ExprKind::AddrOf(_, _, ref e)
|
||||
| hir::ExprKind::Cast(ref e, _)
|
||||
| hir::ExprKind::Type(ref e, _)
|
||||
| hir::ExprKind::DropTemps(ref e)
|
||||
@ -1425,7 +1423,6 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
| hir::ExprKind::Closure { .. }
|
||||
| hir::ExprKind::Path(_)
|
||||
| hir::ExprKind::Yield(..)
|
||||
| hir::ExprKind::Box(..)
|
||||
| hir::ExprKind::Type(..)
|
||||
| hir::ExprKind::Err(_) => {}
|
||||
}
|
||||
|
@ -179,8 +179,7 @@ enum ItemKind {
|
||||
impl<'tcx> CheckInlineAssembly<'tcx> {
|
||||
fn check_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, span: Span) {
|
||||
match expr.kind {
|
||||
ExprKind::Box(..)
|
||||
| ExprKind::ConstBlock(..)
|
||||
ExprKind::ConstBlock(..)
|
||||
| ExprKind::Array(..)
|
||||
| ExprKind::Call(..)
|
||||
| ExprKind::MethodCall(..)
|
||||
|
@ -132,7 +132,7 @@ where
|
||||
projection.trait_ref_and_own_substs(tcx)
|
||||
} else {
|
||||
// HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys
|
||||
let def_id = tcx.impl_trait_in_trait_parent(projection.def_id);
|
||||
let def_id = tcx.impl_trait_in_trait_parent_fn(projection.def_id);
|
||||
let trait_generics = tcx.generics_of(def_id);
|
||||
(
|
||||
tcx.mk_trait_ref(def_id, projection.substs.truncate_to(tcx, trait_generics)),
|
||||
|
@ -2,7 +2,7 @@ use crate::spec::{CodeModel, SanitizerSet, Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Target {
|
||||
Target {
|
||||
llvm_target: "riscv64gc-unknown-fuchsia".into(),
|
||||
llvm_target: "riscv64-unknown-fuchsia".into(),
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
|
||||
arch: "riscv64".into(),
|
||||
|
@ -144,18 +144,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> OnUnimplementedNote {
|
||||
if self.tcx.opt_rpitit_info(obligation.cause.body_id.to_def_id()).is_some() {
|
||||
return OnUnimplementedNote::default();
|
||||
}
|
||||
|
||||
let (def_id, substs) = self
|
||||
.impl_similar_to(trait_ref, obligation)
|
||||
.unwrap_or_else(|| (trait_ref.def_id(), trait_ref.skip_binder().substs));
|
||||
let trait_ref = trait_ref.skip_binder();
|
||||
|
||||
let body_hir = self.tcx.hir().local_def_id_to_hir_id(obligation.cause.body_id);
|
||||
let mut flags =
|
||||
vec![(sym::ItemContext, self.describe_enclosure(body_hir).map(|s| s.to_owned()))];
|
||||
let mut flags = vec![];
|
||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): HIR is not present for RPITITs,
|
||||
// but I guess we could synthesize one here. We don't see any errors that rely on
|
||||
// that yet, though.
|
||||
let enclosure =
|
||||
if let Some(body_hir) = self.tcx.opt_local_def_id_to_hir_id(obligation.cause.body_id) {
|
||||
self.describe_enclosure(body_hir).map(|s| s.to_owned())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
flags.push((sym::ItemContext, enclosure));
|
||||
|
||||
match obligation.cause.code() {
|
||||
ObligationCauseCode::BuiltinDerivedObligation(..)
|
||||
|
@ -2944,9 +2944,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
ObligationCauseCode::SizedYieldType => {
|
||||
err.note("the yield type of a generator must have a statically known size");
|
||||
}
|
||||
ObligationCauseCode::SizedBoxType => {
|
||||
err.note("the type of a box expression must have a statically known size");
|
||||
}
|
||||
ObligationCauseCode::AssignmentLhsSized => {
|
||||
err.note("the left-hand-side of an assignment must have a statically known size");
|
||||
}
|
||||
|
@ -1298,7 +1298,7 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
|
||||
) {
|
||||
let tcx = selcx.tcx();
|
||||
if tcx.def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id);
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent_fn(obligation.predicate.def_id);
|
||||
|
||||
let trait_def_id = tcx.parent(trait_fn_def_id);
|
||||
let trait_substs =
|
||||
@ -2200,7 +2200,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||
let tcx = selcx.tcx();
|
||||
let mut obligations = data.nested;
|
||||
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id);
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent_fn(obligation.predicate.def_id);
|
||||
let leaf_def = match specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) {
|
||||
Ok(assoc_ty) => assoc_ty,
|
||||
Err(guar) => return Progress::error(tcx, guar),
|
||||
|
@ -244,7 +244,7 @@ fn associated_item_for_impl_trait_in_trait(
|
||||
tcx: TyCtxt<'_>,
|
||||
opaque_ty_def_id: LocalDefId,
|
||||
) -> LocalDefId {
|
||||
let fn_def_id = tcx.impl_trait_in_trait_parent(opaque_ty_def_id.to_def_id());
|
||||
let fn_def_id = tcx.impl_trait_in_trait_parent_fn(opaque_ty_def_id.to_def_id());
|
||||
let trait_def_id = tcx.parent(fn_def_id);
|
||||
assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait);
|
||||
|
||||
@ -289,8 +289,39 @@ fn associated_item_for_impl_trait_in_trait(
|
||||
InternalSubsts::identity_for_item(tcx, opaque_ty_def_id.to_def_id()),
|
||||
)));
|
||||
|
||||
// Copy generics_of of the opaque.
|
||||
trait_assoc_ty.generics_of(tcx.generics_of(opaque_ty_def_id).clone());
|
||||
trait_assoc_ty.is_type_alias_impl_trait(false);
|
||||
|
||||
// Copy generics_of of the opaque type item but the trait is the parent.
|
||||
trait_assoc_ty.generics_of({
|
||||
let opaque_ty_generics = tcx.generics_of(opaque_ty_def_id);
|
||||
let opaque_ty_parent_count = opaque_ty_generics.parent_count;
|
||||
let mut params = opaque_ty_generics.params.clone();
|
||||
|
||||
let parent_generics = tcx.generics_of(trait_def_id);
|
||||
let parent_count = parent_generics.parent_count + parent_generics.params.len();
|
||||
|
||||
let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone();
|
||||
|
||||
for param in &mut params {
|
||||
param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32
|
||||
- opaque_ty_parent_count as u32;
|
||||
}
|
||||
|
||||
trait_fn_params.extend(params);
|
||||
params = trait_fn_params;
|
||||
|
||||
let param_def_id_to_index =
|
||||
params.iter().map(|param| (param.def_id, param.index)).collect();
|
||||
|
||||
ty::Generics {
|
||||
parent: Some(trait_def_id),
|
||||
parent_count,
|
||||
params,
|
||||
param_def_id_to_index,
|
||||
has_self: false,
|
||||
has_late_bound_regions: opaque_ty_generics.has_late_bound_regions,
|
||||
}
|
||||
});
|
||||
|
||||
// There are no predicates for the synthesized associated type.
|
||||
trait_assoc_ty.explicit_predicates_of(ty::GenericPredicates {
|
||||
|
@ -117,16 +117,22 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
|
||||
|
||||
/// See `ParamEnv` struct definition for details.
|
||||
fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||
// When computing the param_env of an RPITIT, copy param_env of the containing function. The
|
||||
// synthesized associated type doesn't have extra predicates to assume.
|
||||
if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) {
|
||||
return tcx.param_env(fn_def_id);
|
||||
}
|
||||
|
||||
// Compute the bounds on Self and the type parameters.
|
||||
let ty::InstantiatedPredicates { mut predicates, .. } =
|
||||
tcx.predicates_of(def_id).instantiate_identity(tcx);
|
||||
|
||||
// When computing the param_env of an RPITIT, use predicates of the containing function,
|
||||
// *except* for the additional assumption that the RPITIT normalizes to the trait method's
|
||||
// default opaque type. This is needed to properly check the item bounds of the assoc
|
||||
// type hold (`check_type_bounds`), since that method already installs a similar projection
|
||||
// bound, so they will conflict.
|
||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): I don't like this, we should
|
||||
// at least be making sure that the generics in RPITITs and their parent fn don't
|
||||
// get out of alignment, or else we do actually need to substitute these predicates.
|
||||
if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) {
|
||||
predicates = tcx.predicates_of(fn_def_id).instantiate_identity(tcx).predicates;
|
||||
}
|
||||
|
||||
// Finally, we have to normalize the bounds in the environment, in
|
||||
// case they contain any associated type projections. This process
|
||||
// can yield errors if the put in illegal associated types, like
|
||||
@ -160,7 +166,9 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||
}
|
||||
|
||||
let local_did = def_id.as_local();
|
||||
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
|
||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): This isn't correct for
|
||||
// RPITITs in const trait fn.
|
||||
let hir_id = local_did.and_then(|def_id| tcx.opt_local_def_id_to_hir_id(def_id));
|
||||
|
||||
// FIXME(consts): This is not exactly in line with the constness query.
|
||||
let constness = match hir_id {
|
||||
@ -268,8 +276,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
|
||||
if let ty::Alias(ty::Projection, alias_ty) = *ty.kind()
|
||||
&& self.tcx.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder
|
||||
&& self.tcx.impl_trait_in_trait_parent(alias_ty.def_id) == self.fn_def_id
|
||||
&& self.tcx.is_impl_trait_in_trait(alias_ty.def_id)
|
||||
&& self.tcx.impl_trait_in_trait_parent_fn(alias_ty.def_id) == self.fn_def_id
|
||||
&& self.seen.insert(alias_ty.def_id)
|
||||
{
|
||||
// We have entered some binders as we've walked into the
|
||||
@ -282,11 +290,24 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||
re
|
||||
}
|
||||
});
|
||||
|
||||
// If we're lowering to associated item, install the opaque type which is just
|
||||
// the `type_of` of the trait's associated item. If we're using the old lowering
|
||||
// strategy, then just reinterpret the associated type like an opaque :^)
|
||||
let default_ty = if self.tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
self
|
||||
.tcx
|
||||
.type_of(alias_ty.def_id)
|
||||
.subst(self.tcx, alias_ty.substs)
|
||||
} else {
|
||||
self.tcx.mk_alias(ty::Opaque, alias_ty)
|
||||
};
|
||||
|
||||
self.predicates.push(
|
||||
ty::Binder::bind_with_vars(
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: alias_ty,
|
||||
term: self.tcx.mk_alias(ty::Opaque, alias_ty).into(),
|
||||
term: default_ty.into(),
|
||||
},
|
||||
self.bound_vars,
|
||||
)
|
||||
|
@ -339,6 +339,12 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
|
||||
""
|
||||
};
|
||||
|
||||
// `libtest` uses this to know whether or not to support
|
||||
// `-Zunstable-options`.
|
||||
if !builder.unstable_features() {
|
||||
cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
|
||||
}
|
||||
|
||||
let mut features = String::new();
|
||||
|
||||
// Cranelift doesn't support `asm`.
|
||||
|
@ -426,7 +426,7 @@ fn clean_projection<'tcx>(
|
||||
cx: &mut DocContext<'tcx>,
|
||||
def_id: Option<DefId>,
|
||||
) -> Type {
|
||||
if cx.tcx.def_kind(ty.skip_binder().def_id) == DefKind::ImplTraitPlaceholder {
|
||||
if cx.tcx.is_impl_trait_in_trait(ty.skip_binder().def_id) {
|
||||
let bounds = cx
|
||||
.tcx
|
||||
.explicit_item_bounds(ty.skip_binder().def_id)
|
||||
|
@ -1,12 +1,12 @@
|
||||
# Style for Templates
|
||||
|
||||
This directory has templates in the [Tera templating language](teradoc), which is very
|
||||
similar to [Jinja2](jinjadoc) and [Django](djangodoc) templates, and also to [Askama](askamadoc).
|
||||
This directory has templates in the [Tera templating language][teradoc], which is very
|
||||
similar to [Jinja2][jinjadoc] and [Django][djangodoc] templates, and also to [Askama][askamadoc].
|
||||
|
||||
[teradoc]: https://tera.netlify.app/docs/#templates
|
||||
[jinjadoc]: https://jinja.palletsprojects.com/en/3.0.x/templates/
|
||||
[djangodoc]: https://docs.djangoproject.com/en/3.2/topics/templates/
|
||||
[askamadoc]: https://docs.rs/askama/0.10.5/askama/
|
||||
[jinjadoc]: https://jinja.palletsprojects.com/en/3.1.x/templates/
|
||||
[djangodoc]: https://docs.djangoproject.com/en/4.1/topics/templates/
|
||||
[askamadoc]: https://docs.rs/askama/latest/askama/
|
||||
|
||||
We want our rendered output to have as little unnecessary whitespace as
|
||||
possible, so that pages load quickly. To achieve that we use Tera's
|
||||
@ -30,8 +30,8 @@ contents don't necessarily need a new line.
|
||||
|
||||
Askama templates support quite sophisticated control flow. To keep our templates
|
||||
simple and understandable, we use only a subset: `if` and `for`. In particular
|
||||
we avoid [assignments in the template logic](assignments) and [Askama
|
||||
macros](macros). This also may make things easier if we switch to a different
|
||||
we avoid [assignments in the template logic][assignments] and [Askama
|
||||
macros][macros]. This also may make things easier if we switch to a different
|
||||
Jinja-style template system, like Askama, in the future.
|
||||
|
||||
[assignments]: https://djc.github.io/askama/template_syntax.html#assignments
|
||||
|
@ -167,7 +167,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
||||
Finite
|
||||
},
|
||||
ExprKind::Block(block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)),
|
||||
ExprKind::Box(e) | ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e),
|
||||
ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e),
|
||||
ExprKind::Call(path, _) => {
|
||||
if let ExprKind::Path(ref qpath) = path.kind {
|
||||
cx.qpath_res(qpath, path.hir_id)
|
||||
|
@ -124,8 +124,7 @@ fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'t
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: HirId) -> NeverLoopResult {
|
||||
match expr.kind {
|
||||
ExprKind::Box(e)
|
||||
| ExprKind::Unary(_, e)
|
||||
ExprKind::Unary(_, e)
|
||||
| ExprKind::Cast(e, _)
|
||||
| ExprKind::Type(e, _)
|
||||
| ExprKind::Field(e, _)
|
||||
|
@ -321,7 +321,6 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> {
|
||||
self.has_significant_drop = true;
|
||||
}
|
||||
}
|
||||
ExprKind::Box(..) |
|
||||
ExprKind::Array(..) |
|
||||
ExprKind::Call(..) |
|
||||
ExprKind::Unary(..) |
|
||||
|
@ -33,10 +33,6 @@ struct SortByKeyDetection {
|
||||
/// contains a and the other replaces it with b)
|
||||
fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: &Ident, b_expr: &Expr<'_>, b_ident: &Ident) -> bool {
|
||||
match (&a_expr.kind, &b_expr.kind) {
|
||||
// Two boxes with mirrored contents
|
||||
(ExprKind::Box(left_expr), ExprKind::Box(right_expr)) => {
|
||||
mirrored_exprs(left_expr, a_ident, right_expr, b_ident)
|
||||
},
|
||||
// Two arrays with mirrored contents
|
||||
(ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => {
|
||||
iter::zip(*left_exprs, *right_exprs).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident))
|
||||
|
@ -127,8 +127,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
| ExprKind::Type(inner, _)
|
||||
| ExprKind::Unary(_, inner)
|
||||
| ExprKind::Field(inner, _)
|
||||
| ExprKind::AddrOf(_, _, inner)
|
||||
| ExprKind::Box(inner) => has_no_effect(cx, inner),
|
||||
| ExprKind::AddrOf(_, _, inner) => has_no_effect(cx, inner),
|
||||
ExprKind::Struct(_, fields, ref base) => {
|
||||
!has_drop(cx, cx.typeck_results().expr_ty(expr))
|
||||
&& fields.iter().all(|field| has_no_effect(cx, field.expr))
|
||||
@ -234,8 +233,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
|
||||
| ExprKind::Type(inner, _)
|
||||
| ExprKind::Unary(_, inner)
|
||||
| ExprKind::Field(inner, _)
|
||||
| ExprKind::AddrOf(_, _, inner)
|
||||
| ExprKind::Box(inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
|
||||
| ExprKind::AddrOf(_, _, inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
|
||||
ExprKind::Struct(_, fields, ref base) => {
|
||||
if has_drop(cx, cx.typeck_results().expr_ty(expr)) {
|
||||
None
|
||||
|
@ -213,8 +213,7 @@ fn is_self_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, mut expr: &Expr<'_>, hir_
|
||||
}
|
||||
loop {
|
||||
expr = match expr.kind {
|
||||
ExprKind::Box(e)
|
||||
| ExprKind::AddrOf(_, _, e)
|
||||
ExprKind::AddrOf(_, _, e)
|
||||
| ExprKind::Block(
|
||||
&Block {
|
||||
stmts: [],
|
||||
|
@ -380,7 +380,6 @@ impl<'cx, 'sdt, 'tcx> Visitor<'tcx> for SigDropFinder<'cx, 'sdt, 'tcx> {
|
||||
| hir::ExprKind::Assign(..)
|
||||
| hir::ExprKind::AssignOp(..)
|
||||
| hir::ExprKind::Binary(..)
|
||||
| hir::ExprKind::Box(..)
|
||||
| hir::ExprKind::Call(..)
|
||||
| hir::ExprKind::Field(..)
|
||||
| hir::ExprKind::If(..)
|
||||
|
@ -395,11 +395,6 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
||||
}
|
||||
self.expr(field!(let_expr.init));
|
||||
},
|
||||
ExprKind::Box(inner) => {
|
||||
bind!(self, inner);
|
||||
kind!("Box({inner})");
|
||||
self.expr(inner);
|
||||
},
|
||||
ExprKind::Array(elements) => {
|
||||
bind!(self, elements);
|
||||
kind!("Array({elements})");
|
||||
|
@ -112,7 +112,6 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) {
|
||||
/// Get the search patterns to use for the given expression
|
||||
fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
|
||||
match e.kind {
|
||||
ExprKind::Box(e) => (Pat::Str("box"), expr_search_pat(tcx, e).1),
|
||||
ExprKind::ConstBlock(_) => (Pat::Str("const"), Pat::Str("}")),
|
||||
ExprKind::Tup([]) => (Pat::Str(")"), Pat::Str("(")),
|
||||
ExprKind::Unary(UnOp::Deref, e) => (Pat::Str("*"), expr_search_pat(tcx, e).1),
|
||||
|
@ -199,8 +199,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
|
||||
},
|
||||
|
||||
// Memory allocation, custom operator, loop, or call to an unknown function
|
||||
ExprKind::Box(_)
|
||||
| ExprKind::Unary(..)
|
||||
ExprKind::Unary(..)
|
||||
| ExprKind::Binary(..)
|
||||
| ExprKind::Loop(..)
|
||||
| ExprKind::Call(..) => self.eagerness = Lazy,
|
||||
|
@ -249,7 +249,6 @@ impl HirEqInterExpr<'_, '_, '_> {
|
||||
both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name)
|
||||
&& both(le, re, |l, r| self.eq_expr(l, r))
|
||||
},
|
||||
(&ExprKind::Box(l), &ExprKind::Box(r)) => self.eq_expr(l, r),
|
||||
(&ExprKind::Call(l_fun, l_args), &ExprKind::Call(r_fun, r_args)) => {
|
||||
self.inner.allow_side_effects && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args)
|
||||
},
|
||||
@ -628,7 +627,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||
self.hash_expr(j);
|
||||
}
|
||||
},
|
||||
ExprKind::Box(e) | ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => {
|
||||
ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => {
|
||||
self.hash_expr(e);
|
||||
},
|
||||
ExprKind::Call(fun, args) => {
|
||||
|
@ -133,7 +133,6 @@ impl<'a> Sugg<'a> {
|
||||
|
||||
match expr.kind {
|
||||
hir::ExprKind::AddrOf(..)
|
||||
| hir::ExprKind::Box(..)
|
||||
| hir::ExprKind::If(..)
|
||||
| hir::ExprKind::Let(..)
|
||||
| hir::ExprKind::Closure { .. }
|
||||
|
@ -600,7 +600,6 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
|
||||
helper(typeck, false, e, f)?;
|
||||
},
|
||||
ExprKind::Block(&Block { expr: Some(e), .. }, _)
|
||||
| ExprKind::Box(e)
|
||||
| ExprKind::Cast(e, _)
|
||||
| ExprKind::Unary(_, e) => {
|
||||
helper(typeck, true, e, f)?;
|
||||
|
@ -4,7 +4,7 @@
|
||||
//[NOASSERT] compile-flags: -Coverflow-checks=off
|
||||
|
||||
// CHECK-LABEL: define{{.*}} @assertion
|
||||
// ASSERT: call void @_ZN4core9panicking5panic17h
|
||||
// ASSERT: call void @{{.*4core9panicking5panic}}
|
||||
// NOASSERT: ret i8 0
|
||||
#[no_mangle]
|
||||
pub fn assertion() -> u8 {
|
||||
|
@ -1,5 +1,5 @@
|
||||
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/async-default-fn-overridden.rs:4:12
|
||||
--> $DIR/async-default-fn-overridden.rs:6:12
|
||||
|
|
||||
LL | #![feature(async_fn_in_trait)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
@ -0,0 +1,11 @@
|
||||
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/async-default-fn-overridden.rs:6:12
|
||||
|
|
||||
LL | #![feature(async_fn_in_trait)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -1,5 +1,7 @@
|
||||
// run-pass
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use
|
||||
|
@ -1,33 +1,33 @@
|
||||
error[E0311]: the parameter type `U` may not live long enough
|
||||
--> $DIR/async-generics-and-bounds.rs:12:28
|
||||
--> $DIR/async-generics-and-bounds.rs:14:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics-and-bounds.rs:12:18
|
||||
--> $DIR/async-generics-and-bounds.rs:14:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics-and-bounds.rs:12:28
|
||||
--> $DIR/async-generics-and-bounds.rs:14:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `T` may not live long enough
|
||||
--> $DIR/async-generics-and-bounds.rs:12:28
|
||||
--> $DIR/async-generics-and-bounds.rs:14:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics-and-bounds.rs:12:18
|
||||
--> $DIR/async-generics-and-bounds.rs:14:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics-and-bounds.rs:12:28
|
||||
--> $DIR/async-generics-and-bounds.rs:14:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
@ -0,0 +1,37 @@
|
||||
error[E0311]: the parameter type `U` may not live long enough
|
||||
--> $DIR/async-generics-and-bounds.rs:14:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics-and-bounds.rs:14:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics-and-bounds.rs:14:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `T` may not live long enough
|
||||
--> $DIR/async-generics-and-bounds.rs:14:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics-and-bounds.rs:14:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics-and-bounds.rs:14:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0311`.
|
@ -1,6 +1,8 @@
|
||||
// check-fail
|
||||
// known-bug: #102682
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,33 +1,33 @@
|
||||
error[E0311]: the parameter type `U` may not live long enough
|
||||
--> $DIR/async-generics.rs:9:28
|
||||
--> $DIR/async-generics.rs:11:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics.rs:9:18
|
||||
--> $DIR/async-generics.rs:11:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics.rs:9:28
|
||||
--> $DIR/async-generics.rs:11:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `T` may not live long enough
|
||||
--> $DIR/async-generics.rs:9:28
|
||||
--> $DIR/async-generics.rs:11:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics.rs:9:18
|
||||
--> $DIR/async-generics.rs:11:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics.rs:9:28
|
||||
--> $DIR/async-generics.rs:11:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
37
tests/ui/async-await/in-trait/async-generics.next.stderr
Normal file
37
tests/ui/async-await/in-trait/async-generics.next.stderr
Normal file
@ -0,0 +1,37 @@
|
||||
error[E0311]: the parameter type `U` may not live long enough
|
||||
--> $DIR/async-generics.rs:11:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics.rs:11:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics.rs:11:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `T` may not live long enough
|
||||
--> $DIR/async-generics.rs:11:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/async-generics.rs:11:18
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^
|
||||
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
|
||||
--> $DIR/async-generics.rs:11:28
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0311`.
|
@ -1,6 +1,8 @@
|
||||
// check-fail
|
||||
// known-bug: #102682
|
||||
// edition: 2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/box-coerce-span-in-default.rs:3:12
|
||||
--> $DIR/box-coerce-span-in-default.rs:5:12
|
||||
|
|
||||
LL | #![feature(return_position_impl_trait_in_trait)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@ -0,0 +1,11 @@
|
||||
warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/box-coerce-span-in-default.rs:5:12
|
||||
|
|
||||
LL | #![feature(return_position_impl_trait_in_trait)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -1,4 +1,6 @@
|
||||
// check-pass
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/default-body-type-err-2.rs:8:9
|
||||
--> $DIR/default-body-type-err-2.rs:10:9
|
||||
|
|
||||
LL | 42
|
||||
| ^^- help: try using a conversion method: `.to_string()`
|
@ -0,0 +1,11 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/default-body-type-err-2.rs:10:9
|
||||
|
|
||||
LL | 42
|
||||
| ^^- help: try using a conversion method: `.to_string()`
|
||||
| |
|
||||
| expected `String`, found integer
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -1,4 +1,6 @@
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(async_fn_in_trait)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String`
|
||||
--> $DIR/default-body-type-err.rs:7:22
|
||||
--> $DIR/default-body-type-err.rs:10:22
|
||||
|
|
||||
LL | fn lol(&self) -> impl Deref<Target = String> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String`
|
@ -0,0 +1,12 @@
|
||||
error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String`
|
||||
--> $DIR/default-body-type-err.rs:10:22
|
||||
|
|
||||
LL | fn lol(&self) -> impl Deref<Target = String> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String`
|
||||
LL |
|
||||
LL | &1i32
|
||||
| ----- return type was inferred to be `&i32` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
@ -1,3 +1,6 @@
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
// check-pass
|
||||
// edition:2021
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/default-method-constraint.rs:5:12
|
||||
--> $DIR/default-method-constraint.rs:7:12
|
||||
|
|
||||
LL | #![feature(return_position_impl_trait_in_trait)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@ -0,0 +1,11 @@
|
||||
warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/default-method-constraint.rs:7:12
|
||||
|
|
||||
LL | #![feature(return_position_impl_trait_in_trait)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -1,4 +1,6 @@
|
||||
// check-pass
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
// This didn't work in the previous default RPITIT method hack attempt
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-102571.rs:20:9
|
||||
--> $DIR/issue-102571.rs:23:9
|
||||
|
|
||||
LL | let () = t.bar();
|
||||
| ^^ ------- this expression has type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
|
14
tests/ui/impl-trait/in-trait/issue-102571.next.stderr
Normal file
14
tests/ui/impl-trait/in-trait/issue-102571.next.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-102571.rs:23:9
|
||||
|
|
||||
LL | let () = t.bar();
|
||||
| ^^ ------- this expression has type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
|
||||
| |
|
||||
| expected associated type, found `()`
|
||||
|
|
||||
= note: expected associated type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
|
||||
found unit type `()`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -1,3 +1,6 @@
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0053]: method `bar` has an incompatible type for trait
|
||||
--> $DIR/specialization-broken.rs:16:22
|
||||
--> $DIR/specialization-broken.rs:19:22
|
||||
|
|
||||
LL | default impl<U> Foo for U
|
||||
| - this type parameter
|
||||
@ -11,7 +11,7 @@ LL | fn bar(&self) -> U {
|
||||
| help: change the output type to match the trait: `impl Sized`
|
||||
|
|
||||
note: type in trait
|
||||
--> $DIR/specialization-broken.rs:9:22
|
||||
--> $DIR/specialization-broken.rs:12:22
|
||||
|
|
||||
LL | fn bar(&self) -> impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
@ -19,7 +19,7 @@ LL | fn bar(&self) -> impl Sized;
|
||||
found signature `fn(&U) -> U`
|
||||
|
||||
error: method with return-position `impl Trait` in trait cannot be specialized
|
||||
--> $DIR/specialization-broken.rs:16:5
|
||||
--> $DIR/specialization-broken.rs:19:5
|
||||
|
|
||||
LL | fn bar(&self) -> U {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
@ -0,0 +1,31 @@
|
||||
error[E0053]: method `bar` has an incompatible type for trait
|
||||
--> $DIR/specialization-broken.rs:19:22
|
||||
|
|
||||
LL | default impl<U> Foo for U
|
||||
| - this type parameter
|
||||
...
|
||||
LL | fn bar(&self) -> U {
|
||||
| ^
|
||||
| |
|
||||
| expected associated type, found type parameter `U`
|
||||
| help: change the output type to match the trait: `impl Sized`
|
||||
|
|
||||
note: type in trait
|
||||
--> $DIR/specialization-broken.rs:12:22
|
||||
|
|
||||
LL | fn bar(&self) -> impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
= note: expected signature `fn(&U) -> impl Sized`
|
||||
found signature `fn(&U) -> U`
|
||||
|
||||
error: method with return-position `impl Trait` in trait cannot be specialized
|
||||
--> $DIR/specialization-broken.rs:19:5
|
||||
|
|
||||
LL | fn bar(&self) -> U {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: specialization behaves in inconsistent and surprising ways with `#![feature(return_position_impl_trait_in_trait)]`, and for now is disallowed
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0053`.
|
@ -1,3 +1,6 @@
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
// FIXME(compiler-errors): I'm not exactly sure if this is expected to pass or not.
|
||||
// But we fixed an ICE anyways.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/wf-bounds.rs:9:22
|
||||
--> $DIR/wf-bounds.rs:11:22
|
||||
|
|
||||
LL | fn nya() -> impl Wf<Vec<[u8]>>;
|
||||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
@ -9,14 +9,14 @@ note: required by a bound in `Vec`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/wf-bounds.rs:12:23
|
||||
--> $DIR/wf-bounds.rs:14:23
|
||||
|
|
||||
LL | fn nya2() -> impl Wf<[u8]>;
|
||||
| ^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
note: required by a bound in `Wf`
|
||||
--> $DIR/wf-bounds.rs:6:10
|
||||
--> $DIR/wf-bounds.rs:8:10
|
||||
|
|
||||
LL | trait Wf<T> {}
|
||||
| ^ required by this bound in `Wf`
|
30
tests/ui/impl-trait/in-trait/wf-bounds.next.stderr
Normal file
30
tests/ui/impl-trait/in-trait/wf-bounds.next.stderr
Normal file
@ -0,0 +1,30 @@
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/wf-bounds.rs:11:22
|
||||
|
|
||||
LL | fn nya() -> impl Wf<Vec<[u8]>>;
|
||||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
note: required by a bound in `Vec`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/wf-bounds.rs:14:23
|
||||
|
|
||||
LL | fn nya2() -> impl Wf<[u8]>;
|
||||
| ^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
note: required by a bound in `Wf`
|
||||
--> $DIR/wf-bounds.rs:8:10
|
||||
|
|
||||
LL | trait Wf<T> {}
|
||||
| ^ required by this bound in `Wf`
|
||||
help: consider relaxing the implicit `Sized` restriction
|
||||
|
|
||||
LL | trait Wf<T: ?Sized> {}
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -1,4 +1,6 @@
|
||||
// issue #101663
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
Loading…
Reference in New Issue
Block a user