mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-15 13:36:49 +00:00
Auto merge of #136751 - bjorn3:update_rustfmt, r=Mark-Simulacrum
Update bootstrap compiler and rustfmt The rustfmt version we previously used formats things differently from what the latest nightly rustfmt does. This causes issues for subtrees that get formatted both in-tree and in their own repo. Updating the rustfmt used in-tree solves those issues. Also bumped the bootstrap compiler as the stage0 update command always updates both at the same time.
This commit is contained in:
commit
124cc92199
@ -1184,10 +1184,13 @@ impl Scalar {
|
||||
#[inline]
|
||||
pub fn is_bool(&self) -> bool {
|
||||
use Integer::*;
|
||||
matches!(self, Scalar::Initialized {
|
||||
value: Primitive::Int(I8, false),
|
||||
valid_range: WrappingRange { start: 0, end: 1 }
|
||||
})
|
||||
matches!(
|
||||
self,
|
||||
Scalar::Initialized {
|
||||
value: Primitive::Int(I8, false),
|
||||
valid_range: WrappingRange { start: 0, end: 1 }
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the primitive representation of this type, ignoring the valid range and whether the
|
||||
|
@ -828,15 +828,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
span,
|
||||
Some(Arc::clone(&self.allow_gen_future)),
|
||||
);
|
||||
self.lower_attrs(inner_hir_id, &[Attribute {
|
||||
kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(
|
||||
sym::track_caller,
|
||||
span,
|
||||
)))),
|
||||
id: self.tcx.sess.psess.attr_id_generator.mk_attr_id(),
|
||||
style: AttrStyle::Outer,
|
||||
span: unstable_span,
|
||||
}]);
|
||||
self.lower_attrs(
|
||||
inner_hir_id,
|
||||
&[Attribute {
|
||||
kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(
|
||||
sym::track_caller,
|
||||
span,
|
||||
)))),
|
||||
id: self.tcx.sess.psess.attr_id_generator.mk_attr_id(),
|
||||
style: AttrStyle::Outer,
|
||||
span: unstable_span,
|
||||
}],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,13 +362,16 @@ fn make_format_spec<'hir>(
|
||||
debug_hex,
|
||||
} = &placeholder.format_options;
|
||||
let fill = ctx.expr_char(sp, fill.unwrap_or(' '));
|
||||
let align =
|
||||
ctx.expr_lang_item_type_relative(sp, hir::LangItem::FormatAlignment, match alignment {
|
||||
let align = ctx.expr_lang_item_type_relative(
|
||||
sp,
|
||||
hir::LangItem::FormatAlignment,
|
||||
match alignment {
|
||||
Some(FormatAlignment::Left) => sym::Left,
|
||||
Some(FormatAlignment::Right) => sym::Right,
|
||||
Some(FormatAlignment::Center) => sym::Center,
|
||||
None => sym::Unknown,
|
||||
});
|
||||
},
|
||||
);
|
||||
// This needs to match `Flag` in library/core/src/fmt/rt.rs.
|
||||
let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32)
|
||||
| ((sign == Some(FormatSign::Minus)) as u32) << 1
|
||||
|
@ -304,12 +304,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
this.arena.alloc(this.ty(span, hir::TyKind::Err(guar)))
|
||||
}
|
||||
Some(ty) => this.lower_ty(ty, ImplTraitContext::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias {
|
||||
parent: this.local_def_id(id),
|
||||
in_assoc_ty: false,
|
||||
Some(ty) => this.lower_ty(
|
||||
ty,
|
||||
ImplTraitContext::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias {
|
||||
parent: this.local_def_id(id),
|
||||
in_assoc_ty: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
),
|
||||
},
|
||||
);
|
||||
hir::ItemKind::TyAlias(ty, generics)
|
||||
@ -966,12 +969,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
hir::ImplItemKind::Type(ty)
|
||||
}
|
||||
Some(ty) => {
|
||||
let ty = this.lower_ty(ty, ImplTraitContext::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias {
|
||||
parent: this.local_def_id(i.id),
|
||||
in_assoc_ty: true,
|
||||
let ty = this.lower_ty(
|
||||
ty,
|
||||
ImplTraitContext::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias {
|
||||
parent: this.local_def_id(i.id),
|
||||
in_assoc_ty: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
hir::ImplItemKind::Type(ty)
|
||||
}
|
||||
},
|
||||
@ -1152,10 +1158,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
|
||||
self.lower_body(|this| {
|
||||
(&[], match expr {
|
||||
Some(expr) => this.lower_expr_mut(expr),
|
||||
None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),
|
||||
})
|
||||
(
|
||||
&[],
|
||||
match expr {
|
||||
Some(expr) => this.lower_expr_mut(expr),
|
||||
None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -204,21 +204,27 @@ pub(crate) struct UnsupportedLiteral {
|
||||
|
||||
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
|
||||
let mut diag = Diag::new(dcx, level, match self.reason {
|
||||
UnsupportedLiteralReason::Generic => fluent::attr_parsing_unsupported_literal_generic,
|
||||
UnsupportedLiteralReason::CfgString => {
|
||||
fluent::attr_parsing_unsupported_literal_cfg_string
|
||||
}
|
||||
UnsupportedLiteralReason::CfgBoolean => {
|
||||
fluent::attr_parsing_unsupported_literal_cfg_boolean
|
||||
}
|
||||
UnsupportedLiteralReason::DeprecatedString => {
|
||||
fluent::attr_parsing_unsupported_literal_deprecated_string
|
||||
}
|
||||
UnsupportedLiteralReason::DeprecatedKvPair => {
|
||||
fluent::attr_parsing_unsupported_literal_deprecated_kv_pair
|
||||
}
|
||||
});
|
||||
let mut diag = Diag::new(
|
||||
dcx,
|
||||
level,
|
||||
match self.reason {
|
||||
UnsupportedLiteralReason::Generic => {
|
||||
fluent::attr_parsing_unsupported_literal_generic
|
||||
}
|
||||
UnsupportedLiteralReason::CfgString => {
|
||||
fluent::attr_parsing_unsupported_literal_cfg_string
|
||||
}
|
||||
UnsupportedLiteralReason::CfgBoolean => {
|
||||
fluent::attr_parsing_unsupported_literal_cfg_boolean
|
||||
}
|
||||
UnsupportedLiteralReason::DeprecatedString => {
|
||||
fluent::attr_parsing_unsupported_literal_deprecated_string
|
||||
}
|
||||
UnsupportedLiteralReason::DeprecatedKvPair => {
|
||||
fluent::attr_parsing_unsupported_literal_deprecated_kv_pair
|
||||
}
|
||||
},
|
||||
);
|
||||
diag.span(self.span);
|
||||
diag.code(E0565);
|
||||
if self.is_bytestr {
|
||||
|
@ -156,24 +156,25 @@ pub(crate) trait TypeOpInfo<'tcx> {
|
||||
return;
|
||||
};
|
||||
|
||||
let placeholder_region = ty::Region::new_placeholder(tcx, ty::Placeholder {
|
||||
universe: adjusted_universe.into(),
|
||||
bound: placeholder.bound,
|
||||
});
|
||||
let placeholder_region = ty::Region::new_placeholder(
|
||||
tcx,
|
||||
ty::Placeholder { universe: adjusted_universe.into(), bound: placeholder.bound },
|
||||
);
|
||||
|
||||
let error_region =
|
||||
if let RegionElement::PlaceholderRegion(error_placeholder) = error_element {
|
||||
let adjusted_universe =
|
||||
error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
|
||||
adjusted_universe.map(|adjusted| {
|
||||
ty::Region::new_placeholder(tcx, ty::Placeholder {
|
||||
universe: adjusted.into(),
|
||||
bound: error_placeholder.bound,
|
||||
})
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let error_region = if let RegionElement::PlaceholderRegion(error_placeholder) =
|
||||
error_element
|
||||
{
|
||||
let adjusted_universe =
|
||||
error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
|
||||
adjusted_universe.map(|adjusted| {
|
||||
ty::Region::new_placeholder(
|
||||
tcx,
|
||||
ty::Placeholder { universe: adjusted.into(), bound: error_placeholder.bound },
|
||||
)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
debug!(?placeholder_region);
|
||||
|
||||
|
@ -147,10 +147,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
span,
|
||||
desired_action.as_noun(),
|
||||
partially_str,
|
||||
self.describe_place_with_options(moved_place, DescribePlaceOpt {
|
||||
including_downcast: true,
|
||||
including_tuple_field: true,
|
||||
}),
|
||||
self.describe_place_with_options(
|
||||
moved_place,
|
||||
DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
|
||||
),
|
||||
);
|
||||
|
||||
let reinit_spans = maybe_reinitialized_locations
|
||||
@ -280,10 +280,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
self.suggest_adding_bounds(&mut err, ty, copy_did, span);
|
||||
}
|
||||
|
||||
let opt_name = self.describe_place_with_options(place.as_ref(), DescribePlaceOpt {
|
||||
including_downcast: true,
|
||||
including_tuple_field: true,
|
||||
});
|
||||
let opt_name = self.describe_place_with_options(
|
||||
place.as_ref(),
|
||||
DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
|
||||
);
|
||||
let note_msg = match opt_name {
|
||||
Some(name) => format!("`{name}`"),
|
||||
None => "value".to_owned(),
|
||||
@ -765,17 +765,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
}
|
||||
let spans: Vec<_> = spans_set.into_iter().collect();
|
||||
|
||||
let (name, desc) = match self.describe_place_with_options(moved_place, DescribePlaceOpt {
|
||||
including_downcast: true,
|
||||
including_tuple_field: true,
|
||||
}) {
|
||||
let (name, desc) = match self.describe_place_with_options(
|
||||
moved_place,
|
||||
DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
|
||||
) {
|
||||
Some(name) => (format!("`{name}`"), format!("`{name}` ")),
|
||||
None => ("the variable".to_string(), String::new()),
|
||||
};
|
||||
let path = match self.describe_place_with_options(used_place, DescribePlaceOpt {
|
||||
including_downcast: true,
|
||||
including_tuple_field: true,
|
||||
}) {
|
||||
let path = match self.describe_place_with_options(
|
||||
used_place,
|
||||
DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
|
||||
) {
|
||||
Some(name) => format!("`{name}`"),
|
||||
None => "value".to_string(),
|
||||
};
|
||||
|
@ -304,10 +304,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
/// End-user visible description of `place` if one can be found.
|
||||
/// If the place is a temporary for instance, `None` will be returned.
|
||||
pub(super) fn describe_place(&self, place_ref: PlaceRef<'tcx>) -> Option<String> {
|
||||
self.describe_place_with_options(place_ref, DescribePlaceOpt {
|
||||
including_downcast: false,
|
||||
including_tuple_field: true,
|
||||
})
|
||||
self.describe_place_with_options(
|
||||
place_ref,
|
||||
DescribePlaceOpt { including_downcast: false, including_tuple_field: true },
|
||||
)
|
||||
}
|
||||
|
||||
/// End-user visible description of `place` if one can be found. If the place is a temporary
|
||||
|
@ -1100,12 +1100,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
let closure_ty = Ty::new_closure(
|
||||
tcx,
|
||||
closure_def_id.to_def_id(),
|
||||
ty::ClosureArgs::new(tcx, ty::ClosureArgsParts {
|
||||
parent_args: args.parent_args(),
|
||||
closure_kind_ty: args.kind_ty(),
|
||||
tupled_upvars_ty: args.tupled_upvars_ty(),
|
||||
closure_sig_as_fn_ptr_ty,
|
||||
})
|
||||
ty::ClosureArgs::new(
|
||||
tcx,
|
||||
ty::ClosureArgsParts {
|
||||
parent_args: args.parent_args(),
|
||||
closure_kind_ty: args.kind_ty(),
|
||||
tupled_upvars_ty: args.tupled_upvars_ty(),
|
||||
closure_sig_as_fn_ptr_ty,
|
||||
},
|
||||
)
|
||||
.args,
|
||||
);
|
||||
|
||||
|
@ -1668,9 +1668,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
||||
match elem {
|
||||
ProjectionElem::Deref => match place_ty.ty.kind() {
|
||||
ty::Ref(..) | ty::RawPtr(..) => {
|
||||
self.move_errors.push(MoveError::new(place, location, BorrowedContent {
|
||||
target_place: place_ref.project_deeper(&[elem], tcx),
|
||||
}));
|
||||
self.move_errors.push(MoveError::new(
|
||||
place,
|
||||
location,
|
||||
BorrowedContent {
|
||||
target_place: place_ref.project_deeper(&[elem], tcx),
|
||||
},
|
||||
));
|
||||
return;
|
||||
}
|
||||
ty::Adt(adt, _) => {
|
||||
|
@ -166,10 +166,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
|
||||
prev.span = prev.span.substitute_dummy(concrete_type.span);
|
||||
} else {
|
||||
result.insert(opaque_type_key.def_id, OpaqueHiddenType {
|
||||
ty,
|
||||
span: concrete_type.span,
|
||||
});
|
||||
result.insert(
|
||||
opaque_type_key.def_id,
|
||||
OpaqueHiddenType { ty, span: concrete_type.span },
|
||||
);
|
||||
}
|
||||
|
||||
// Check that all opaque types have the same region parameters if they have the same
|
||||
|
@ -75,17 +75,20 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
let output_ty = Ty::new_coroutine(
|
||||
self.tcx(),
|
||||
self.tcx().coroutine_for_closure(mir_def_id),
|
||||
ty::CoroutineArgs::new(self.tcx(), ty::CoroutineArgsParts {
|
||||
parent_args: args.parent_args(),
|
||||
kind_ty: Ty::from_coroutine_closure_kind(self.tcx(), args.kind()),
|
||||
return_ty: user_provided_sig.output(),
|
||||
tupled_upvars_ty,
|
||||
// For async closures, none of these can be annotated, so just fill
|
||||
// them with fresh ty vars.
|
||||
resume_ty: next_ty_var(),
|
||||
yield_ty: next_ty_var(),
|
||||
witness: next_ty_var(),
|
||||
})
|
||||
ty::CoroutineArgs::new(
|
||||
self.tcx(),
|
||||
ty::CoroutineArgsParts {
|
||||
parent_args: args.parent_args(),
|
||||
kind_ty: Ty::from_coroutine_closure_kind(self.tcx(), args.kind()),
|
||||
return_ty: user_provided_sig.output(),
|
||||
tupled_upvars_ty,
|
||||
// For async closures, none of these can be annotated, so just fill
|
||||
// them with fresh ty vars.
|
||||
resume_ty: next_ty_var(),
|
||||
yield_ty: next_ty_var(),
|
||||
witness: next_ty_var(),
|
||||
},
|
||||
)
|
||||
.args,
|
||||
);
|
||||
|
||||
|
@ -411,10 +411,10 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
} else {
|
||||
self.typeck.ascribe_user_type(
|
||||
constant.const_.ty(),
|
||||
ty::UserType::new(ty::UserTypeKind::TypeOf(uv.def, UserArgs {
|
||||
args: uv.args,
|
||||
user_self_ty: None,
|
||||
})),
|
||||
ty::UserType::new(ty::UserTypeKind::TypeOf(
|
||||
uv.def,
|
||||
UserArgs { args: uv.args, user_self_ty: None },
|
||||
)),
|
||||
locations.span(self.typeck.body),
|
||||
);
|
||||
}
|
||||
@ -1642,10 +1642,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
|
||||
let trait_ref =
|
||||
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, Some(span)), [
|
||||
ty,
|
||||
]);
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(span)),
|
||||
[ty],
|
||||
);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -1659,10 +1660,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
Rvalue::ShallowInitBox(operand, ty) => {
|
||||
self.check_operand(operand, location);
|
||||
|
||||
let trait_ref =
|
||||
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, Some(span)), [
|
||||
*ty,
|
||||
]);
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(span)),
|
||||
[*ty],
|
||||
);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
|
@ -620,10 +620,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
let ty = tcx
|
||||
.typeck(self.mir_def)
|
||||
.node_type(tcx.local_def_id_to_hir_id(self.mir_def));
|
||||
let args = InlineConstArgs::new(tcx, InlineConstArgsParts {
|
||||
parent_args: identity_args,
|
||||
ty,
|
||||
})
|
||||
let args = InlineConstArgs::new(
|
||||
tcx,
|
||||
InlineConstArgsParts { parent_args: identity_args, ty },
|
||||
)
|
||||
.args;
|
||||
let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, args);
|
||||
DefiningTy::InlineConst(self.mir_def.to_def_id(), args)
|
||||
|
@ -67,10 +67,11 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
|
||||
|
||||
let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
|
||||
let layout_new = cx.expr_path(cx.path(span, layout_new));
|
||||
let layout = cx.expr_call(span, layout_new, thin_vec![
|
||||
cx.expr_ident(span, size),
|
||||
cx.expr_ident(span, align)
|
||||
]);
|
||||
let layout = cx.expr_call(
|
||||
span,
|
||||
layout_new,
|
||||
thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)],
|
||||
);
|
||||
|
||||
let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]);
|
||||
|
||||
|
@ -406,19 +406,21 @@ mod llvm_enzyme {
|
||||
let unsf_expr = ecx.expr_block(P(unsf_block));
|
||||
let blackbox_call_expr = ecx.expr_path(ecx.path(span, blackbox_path));
|
||||
let primal_call = gen_primal_call(ecx, span, primal, idents);
|
||||
let black_box_primal_call =
|
||||
ecx.expr_call(new_decl_span, blackbox_call_expr.clone(), thin_vec![
|
||||
primal_call.clone()
|
||||
]);
|
||||
let black_box_primal_call = ecx.expr_call(
|
||||
new_decl_span,
|
||||
blackbox_call_expr.clone(),
|
||||
thin_vec![primal_call.clone()],
|
||||
);
|
||||
let tup_args = new_names
|
||||
.iter()
|
||||
.map(|arg| ecx.expr_path(ecx.path_ident(span, Ident::from_str(arg))))
|
||||
.collect();
|
||||
|
||||
let black_box_remaining_args =
|
||||
ecx.expr_call(sig_span, blackbox_call_expr.clone(), thin_vec![
|
||||
ecx.expr_tuple(sig_span, tup_args)
|
||||
]);
|
||||
let black_box_remaining_args = ecx.expr_call(
|
||||
sig_span,
|
||||
blackbox_call_expr.clone(),
|
||||
thin_vec![ecx.expr_tuple(sig_span, tup_args)],
|
||||
);
|
||||
|
||||
let mut body = ecx.block(span, ThinVec::new());
|
||||
body.stmts.push(ecx.stmt_semi(unsf_expr));
|
||||
@ -532,8 +534,11 @@ mod llvm_enzyme {
|
||||
return body;
|
||||
}
|
||||
[arg] => {
|
||||
ret = ecx
|
||||
.expr_call(new_decl_span, blackbox_call_expr.clone(), thin_vec![arg.clone()]);
|
||||
ret = ecx.expr_call(
|
||||
new_decl_span,
|
||||
blackbox_call_expr.clone(),
|
||||
thin_vec![arg.clone()],
|
||||
);
|
||||
}
|
||||
args => {
|
||||
let ret_tuple: P<ast::Expr> = ecx.expr_tuple(span, args.into());
|
||||
|
@ -114,10 +114,13 @@ fn cs_clone_simple(
|
||||
// type parameters.
|
||||
} else {
|
||||
// let _: AssertParamIsClone<FieldTy>;
|
||||
super::assert_ty_bounds(cx, &mut stmts, field.ty.clone(), field.span, &[
|
||||
sym::clone,
|
||||
sym::AssertParamIsClone,
|
||||
]);
|
||||
super::assert_ty_bounds(
|
||||
cx,
|
||||
&mut stmts,
|
||||
field.ty.clone(),
|
||||
field.span,
|
||||
&[sym::clone, sym::AssertParamIsClone],
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -126,10 +129,13 @@ fn cs_clone_simple(
|
||||
// Just a single assertion for unions, that the union impls `Copy`.
|
||||
// let _: AssertParamIsCopy<Self>;
|
||||
let self_ty = cx.ty_path(cx.path_ident(trait_span, Ident::with_dummy_span(kw::SelfUpper)));
|
||||
super::assert_ty_bounds(cx, &mut stmts, self_ty, trait_span, &[
|
||||
sym::clone,
|
||||
sym::AssertParamIsCopy,
|
||||
]);
|
||||
super::assert_ty_bounds(
|
||||
cx,
|
||||
&mut stmts,
|
||||
self_ty,
|
||||
trait_span,
|
||||
&[sym::clone, sym::AssertParamIsCopy],
|
||||
);
|
||||
} else {
|
||||
match *substr.fields {
|
||||
StaticStruct(vdata, ..) => {
|
||||
|
@ -65,10 +65,13 @@ fn cs_total_eq_assert(
|
||||
// Already produced an assertion for this type.
|
||||
} else {
|
||||
// let _: AssertParamIsEq<FieldTy>;
|
||||
super::assert_ty_bounds(cx, &mut stmts, field.ty.clone(), field.span, &[
|
||||
sym::cmp,
|
||||
sym::AssertParamIsEq,
|
||||
]);
|
||||
super::assert_ty_bounds(
|
||||
cx,
|
||||
&mut stmts,
|
||||
field.ty.clone(),
|
||||
field.span,
|
||||
&[sym::cmp, sym::AssertParamIsEq],
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -108,30 +108,38 @@ fn default_enum_substructure(
|
||||
Ok(default_variant) => {
|
||||
// We now know there is exactly one unit variant with exactly one `#[default]` attribute.
|
||||
match &default_variant.data {
|
||||
VariantData::Unit(_) => cx.expr_path(cx.path(default_variant.span, vec![
|
||||
Ident::new(kw::SelfUpper, default_variant.span),
|
||||
default_variant.ident,
|
||||
])),
|
||||
VariantData::Unit(_) => cx.expr_path(cx.path(
|
||||
default_variant.span,
|
||||
vec![Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident],
|
||||
)),
|
||||
VariantData::Struct { fields, .. } => {
|
||||
// This only happens if `#![feature(default_field_values)]`. We have validated
|
||||
// all fields have default values in the definition.
|
||||
let default_fields = fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
cx.field_imm(field.span, field.ident.unwrap(), match &field.default {
|
||||
// We use `Default::default()`.
|
||||
None => default_call(cx, field.span),
|
||||
// We use the field default const expression.
|
||||
Some(val) => {
|
||||
cx.expr(val.value.span, ast::ExprKind::ConstBlock(val.clone()))
|
||||
}
|
||||
})
|
||||
cx.field_imm(
|
||||
field.span,
|
||||
field.ident.unwrap(),
|
||||
match &field.default {
|
||||
// We use `Default::default()`.
|
||||
None => default_call(cx, field.span),
|
||||
// We use the field default const expression.
|
||||
Some(val) => cx.expr(
|
||||
val.value.span,
|
||||
ast::ExprKind::ConstBlock(val.clone()),
|
||||
),
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
let path = cx.path(default_variant.span, vec![
|
||||
Ident::new(kw::SelfUpper, default_variant.span),
|
||||
default_variant.ident,
|
||||
]);
|
||||
let path = cx.path(
|
||||
default_variant.span,
|
||||
vec![
|
||||
Ident::new(kw::SelfUpper, default_variant.span),
|
||||
default_variant.ident,
|
||||
],
|
||||
);
|
||||
cx.expr_struct(default_variant.span, path, default_fields)
|
||||
}
|
||||
// Logic error in `extract_default_variant`.
|
||||
|
@ -1220,10 +1220,12 @@ impl<'a> MethodDef<'a> {
|
||||
|
||||
let discr_let_stmts: ThinVec<_> = iter::zip(&discr_idents, &selflike_args)
|
||||
.map(|(&ident, selflike_arg)| {
|
||||
let variant_value =
|
||||
deriving::call_intrinsic(cx, span, sym::discriminant_value, thin_vec![
|
||||
selflike_arg.clone()
|
||||
]);
|
||||
let variant_value = deriving::call_intrinsic(
|
||||
cx,
|
||||
span,
|
||||
sym::discriminant_value,
|
||||
thin_vec![selflike_arg.clone()],
|
||||
);
|
||||
cx.stmt_let(span, false, ident, variant_value)
|
||||
})
|
||||
.collect();
|
||||
|
@ -77,11 +77,11 @@ pub(crate) fn expand_option_env<'cx>(
|
||||
let guar = cx.dcx().emit_err(errors::EnvNotUnicode { span: sp, var: *symbol });
|
||||
return ExpandResult::Ready(DummyResult::any(sp, guar));
|
||||
}
|
||||
Ok(value) => {
|
||||
cx.expr_call_global(sp, cx.std_path(&[sym::option, sym::Option, sym::Some]), thin_vec![
|
||||
cx.expr_str(sp, value)
|
||||
])
|
||||
}
|
||||
Ok(value) => cx.expr_call_global(
|
||||
sp,
|
||||
cx.std_path(&[sym::option, sym::Option, sym::Some]),
|
||||
thin_vec![cx.expr_str(sp, value)],
|
||||
),
|
||||
};
|
||||
ExpandResult::Ready(MacEager::expr(e))
|
||||
}
|
||||
|
@ -183,10 +183,14 @@ pub(crate) mod printf {
|
||||
s.push('{');
|
||||
|
||||
if let Some(arg) = self.parameter {
|
||||
match write!(s, "{}", match arg.checked_sub(1) {
|
||||
Some(a) => a,
|
||||
None => return Err(None),
|
||||
}) {
|
||||
match write!(
|
||||
s,
|
||||
"{}",
|
||||
match arg.checked_sub(1) {
|
||||
Some(a) => a,
|
||||
None => return Err(None),
|
||||
}
|
||||
) {
|
||||
Err(_) => return Err(None),
|
||||
_ => {}
|
||||
}
|
||||
|
@ -99,12 +99,10 @@ fn test_parse() {
|
||||
fn test_iter() {
|
||||
let s = "The %d'th word %% is: `%.*s` %!\n";
|
||||
let subs: Vec<_> = iter_subs(s, 0).map(|sub| sub.translate().ok()).collect();
|
||||
assert_eq!(subs.iter().map(Option::as_deref).collect::<Vec<_>>(), vec![
|
||||
Some("{}"),
|
||||
None,
|
||||
Some("{:.*}"),
|
||||
None
|
||||
]);
|
||||
assert_eq!(
|
||||
subs.iter().map(Option::as_deref).collect::<Vec<_>>(),
|
||||
vec![Some("{}"), None, Some("{:.*}"), None]
|
||||
);
|
||||
}
|
||||
|
||||
/// Checks that the translations are what we expect.
|
||||
|
@ -38,11 +38,10 @@ fn test_iter() {
|
||||
use super::iter_subs;
|
||||
let s = "The $0'th word $$ is: `$WORD` $!\n";
|
||||
let subs: Vec<_> = iter_subs(s, 0).map(|sub| sub.translate().ok()).collect();
|
||||
assert_eq!(subs.iter().map(Option::as_deref).collect::<Vec<_>>(), vec![
|
||||
Some("{0}"),
|
||||
None,
|
||||
Some("{WORD}")
|
||||
]);
|
||||
assert_eq!(
|
||||
subs.iter().map(Option::as_deref).collect::<Vec<_>>(),
|
||||
vec![Some("{0}"), None, Some("{WORD}")]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -301,13 +301,10 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
|
||||
};
|
||||
let local_path = |cx: &ExtCtxt<'_>, name| cx.expr_path(cx.path(span, vec![name]));
|
||||
let proc_macro_ty_method_path = |cx: &ExtCtxt<'_>, method| {
|
||||
cx.expr_path(cx.path(span.with_ctxt(harness_span.ctxt()), vec![
|
||||
proc_macro,
|
||||
bridge,
|
||||
client,
|
||||
proc_macro_ty,
|
||||
method,
|
||||
]))
|
||||
cx.expr_path(cx.path(
|
||||
span.with_ctxt(harness_span.ctxt()),
|
||||
vec![proc_macro, bridge, client, proc_macro_ty, method],
|
||||
))
|
||||
};
|
||||
match m {
|
||||
ProcMacro::Derive(cd) => {
|
||||
@ -340,10 +337,14 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
|
||||
|
||||
// The call needs to use `harness_span` so that the const stability checker
|
||||
// accepts it.
|
||||
cx.expr_call(harness_span, proc_macro_ty_method_path(cx, ident), thin_vec![
|
||||
cx.expr_str(span, ca.function_name.name),
|
||||
local_path(cx, ca.function_name),
|
||||
])
|
||||
cx.expr_call(
|
||||
harness_span,
|
||||
proc_macro_ty_method_path(cx, ident),
|
||||
thin_vec![
|
||||
cx.expr_str(span, ca.function_name.name),
|
||||
local_path(cx, ca.function_name),
|
||||
],
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -357,12 +358,9 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
|
||||
span,
|
||||
cx.ty(
|
||||
span,
|
||||
ast::TyKind::Slice(cx.ty_path(cx.path(span, vec![
|
||||
proc_macro,
|
||||
bridge,
|
||||
client,
|
||||
proc_macro_ty,
|
||||
]))),
|
||||
ast::TyKind::Slice(
|
||||
cx.ty_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty])),
|
||||
),
|
||||
),
|
||||
None,
|
||||
ast::Mutability::Not,
|
||||
|
@ -169,20 +169,26 @@ pub(crate) fn expand_test_or_bench(
|
||||
|
||||
// creates test::ShouldPanic::$name
|
||||
let should_panic_path = |name| {
|
||||
cx.path(sp, vec![
|
||||
test_id,
|
||||
Ident::from_str_and_span("ShouldPanic", sp),
|
||||
Ident::from_str_and_span(name, sp),
|
||||
])
|
||||
cx.path(
|
||||
sp,
|
||||
vec![
|
||||
test_id,
|
||||
Ident::from_str_and_span("ShouldPanic", sp),
|
||||
Ident::from_str_and_span(name, sp),
|
||||
],
|
||||
)
|
||||
};
|
||||
|
||||
// creates test::TestType::$name
|
||||
let test_type_path = |name| {
|
||||
cx.path(sp, vec![
|
||||
test_id,
|
||||
Ident::from_str_and_span("TestType", sp),
|
||||
Ident::from_str_and_span(name, sp),
|
||||
])
|
||||
cx.path(
|
||||
sp,
|
||||
vec![
|
||||
test_id,
|
||||
Ident::from_str_and_span("TestType", sp),
|
||||
Ident::from_str_and_span(name, sp),
|
||||
],
|
||||
)
|
||||
};
|
||||
|
||||
// creates $name: $expr
|
||||
@ -202,39 +208,55 @@ pub(crate) fn expand_test_or_bench(
|
||||
// A simple ident for a lambda
|
||||
let b = Ident::from_str_and_span("b", attr_sp);
|
||||
|
||||
cx.expr_call(sp, cx.expr_path(test_path("StaticBenchFn")), thin_vec![
|
||||
// #[coverage(off)]
|
||||
// |b| self::test::assert_test_result(
|
||||
coverage_off(cx.lambda1(
|
||||
sp,
|
||||
cx.expr_call(sp, cx.expr_path(test_path("assert_test_result")), thin_vec![
|
||||
// super::$test_fn(b)
|
||||
cx.expr_call(
|
||||
sp,
|
||||
cx.expr_path(test_path("StaticBenchFn")),
|
||||
thin_vec![
|
||||
// #[coverage(off)]
|
||||
// |b| self::test::assert_test_result(
|
||||
coverage_off(cx.lambda1(
|
||||
sp,
|
||||
cx.expr_call(
|
||||
ret_ty_sp,
|
||||
cx.expr_path(cx.path(sp, vec![item.ident])),
|
||||
thin_vec![cx.expr_ident(sp, b)],
|
||||
sp,
|
||||
cx.expr_path(test_path("assert_test_result")),
|
||||
thin_vec![
|
||||
// super::$test_fn(b)
|
||||
cx.expr_call(
|
||||
ret_ty_sp,
|
||||
cx.expr_path(cx.path(sp, vec![item.ident])),
|
||||
thin_vec![cx.expr_ident(sp, b)],
|
||||
),
|
||||
],
|
||||
),
|
||||
],),
|
||||
b,
|
||||
)), // )
|
||||
])
|
||||
b,
|
||||
)), // )
|
||||
],
|
||||
)
|
||||
} else {
|
||||
cx.expr_call(sp, cx.expr_path(test_path("StaticTestFn")), thin_vec![
|
||||
// #[coverage(off)]
|
||||
// || {
|
||||
coverage_off(cx.lambda0(
|
||||
sp,
|
||||
// test::assert_test_result(
|
||||
cx.expr_call(sp, cx.expr_path(test_path("assert_test_result")), thin_vec![
|
||||
// $test_fn()
|
||||
cx.expr_call(
|
||||
sp,
|
||||
cx.expr_path(test_path("StaticTestFn")),
|
||||
thin_vec![
|
||||
// #[coverage(off)]
|
||||
// || {
|
||||
coverage_off(cx.lambda0(
|
||||
sp,
|
||||
// test::assert_test_result(
|
||||
cx.expr_call(
|
||||
ret_ty_sp,
|
||||
cx.expr_path(cx.path(sp, vec![item.ident])),
|
||||
ThinVec::new(),
|
||||
), // )
|
||||
],), // }
|
||||
)), // )
|
||||
])
|
||||
sp,
|
||||
cx.expr_path(test_path("assert_test_result")),
|
||||
thin_vec![
|
||||
// $test_fn()
|
||||
cx.expr_call(
|
||||
ret_ty_sp,
|
||||
cx.expr_path(cx.path(sp, vec![item.ident])),
|
||||
ThinVec::new(),
|
||||
), // )
|
||||
],
|
||||
), // }
|
||||
)), // )
|
||||
],
|
||||
)
|
||||
};
|
||||
|
||||
let test_path_symbol = Symbol::intern(&item_path(
|
||||
@ -245,26 +267,30 @@ pub(crate) fn expand_test_or_bench(
|
||||
|
||||
let location_info = get_location_info(cx, &item);
|
||||
|
||||
let mut test_const = cx.item(
|
||||
sp,
|
||||
Ident::new(item.ident.name, sp),
|
||||
thin_vec![
|
||||
// #[cfg(test)]
|
||||
cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
|
||||
// #[rustc_test_marker = "test_case_sort_key"]
|
||||
cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp),
|
||||
// #[doc(hidden)]
|
||||
cx.attr_nested_word(sym::doc, sym::hidden, attr_sp),
|
||||
],
|
||||
// const $ident: test::TestDescAndFn =
|
||||
ast::ItemKind::Const(
|
||||
ast::ConstItem {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
generics: ast::Generics::default(),
|
||||
ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
|
||||
// test::TestDescAndFn {
|
||||
expr: Some(
|
||||
cx.expr_struct(sp, test_path("TestDescAndFn"), thin_vec![
|
||||
let mut test_const =
|
||||
cx.item(
|
||||
sp,
|
||||
Ident::new(item.ident.name, sp),
|
||||
thin_vec![
|
||||
// #[cfg(test)]
|
||||
cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
|
||||
// #[rustc_test_marker = "test_case_sort_key"]
|
||||
cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp),
|
||||
// #[doc(hidden)]
|
||||
cx.attr_nested_word(sym::doc, sym::hidden, attr_sp),
|
||||
],
|
||||
// const $ident: test::TestDescAndFn =
|
||||
ast::ItemKind::Const(
|
||||
ast::ConstItem {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
generics: ast::Generics::default(),
|
||||
ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
|
||||
// test::TestDescAndFn {
|
||||
expr: Some(
|
||||
cx.expr_struct(
|
||||
sp,
|
||||
test_path("TestDescAndFn"),
|
||||
thin_vec![
|
||||
// desc: test::TestDesc {
|
||||
field(
|
||||
"desc",
|
||||
@ -340,12 +366,13 @@ pub(crate) fn expand_test_or_bench(
|
||||
),
|
||||
// testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
|
||||
field("testfn", test_fn), // }
|
||||
]), // }
|
||||
),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
);
|
||||
],
|
||||
), // }
|
||||
),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
);
|
||||
test_const = test_const.map(|mut tc| {
|
||||
tc.vis.kind = ast::VisibilityKind::Public;
|
||||
tc
|
||||
|
@ -241,9 +241,10 @@ unsafe fn test_simd() {
|
||||
let (zero0, zero1) = std::mem::transmute::<_, (u64, u64)>(x);
|
||||
assert_eq!((zero0, zero1), (0, 0));
|
||||
assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]);
|
||||
assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_eq), [
|
||||
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
|
||||
]);
|
||||
assert_eq!(
|
||||
std::mem::transmute::<_, [u16; 8]>(cmp_eq),
|
||||
[0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff]
|
||||
);
|
||||
assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_lt), [0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
test_mm_slli_si128();
|
||||
|
@ -96,9 +96,12 @@ pub(crate) fn clif_int_or_float_cast(
|
||||
},
|
||||
);
|
||||
|
||||
fx.lib_call(&name, vec![AbiParam::new(from_ty)], vec![AbiParam::new(types::I128)], &[
|
||||
from,
|
||||
])[0]
|
||||
fx.lib_call(
|
||||
&name,
|
||||
vec![AbiParam::new(from_ty)],
|
||||
vec![AbiParam::new(types::I128)],
|
||||
&[from],
|
||||
)[0]
|
||||
} else if to_ty == types::I8 || to_ty == types::I16 {
|
||||
// FIXME implement fcvt_to_*int_sat.i8/i16
|
||||
let val = if to_signed {
|
||||
|
@ -73,16 +73,19 @@ impl WriteDebugInfo for ObjectProduct {
|
||||
}
|
||||
};
|
||||
self.object
|
||||
.add_relocation(from.0, Relocation {
|
||||
offset: u64::from(reloc.offset),
|
||||
symbol,
|
||||
flags: RelocationFlags::Generic {
|
||||
kind: reloc.kind,
|
||||
encoding: RelocationEncoding::Generic,
|
||||
size: reloc.size * 8,
|
||||
.add_relocation(
|
||||
from.0,
|
||||
Relocation {
|
||||
offset: u64::from(reloc.offset),
|
||||
symbol,
|
||||
flags: RelocationFlags::Generic {
|
||||
kind: reloc.kind,
|
||||
encoding: RelocationEncoding::Generic,
|
||||
size: reloc.size * 8,
|
||||
},
|
||||
addend: i64::try_from(symbol_offset).unwrap() + reloc.addend,
|
||||
},
|
||||
addend: i64::try_from(symbol_offset).unwrap() + reloc.addend,
|
||||
})
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -342,11 +342,15 @@ fn codegen_shim<'tcx>(
|
||||
let instance_ptr = Box::into_raw(Box::new(inst));
|
||||
|
||||
let jit_fn = module
|
||||
.declare_function("__clif_jit_fn", Linkage::Import, &Signature {
|
||||
call_conv: module.target_config().default_call_conv,
|
||||
params: vec![AbiParam::new(pointer_type), AbiParam::new(pointer_type)],
|
||||
returns: vec![AbiParam::new(pointer_type)],
|
||||
})
|
||||
.declare_function(
|
||||
"__clif_jit_fn",
|
||||
Linkage::Import,
|
||||
&Signature {
|
||||
call_conv: module.target_config().default_call_conv,
|
||||
params: vec![AbiParam::new(pointer_type), AbiParam::new(pointer_type)],
|
||||
returns: vec![AbiParam::new(pointer_type)],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let context = cached_context;
|
||||
|
@ -875,11 +875,15 @@ fn call_inline_asm<'tcx>(
|
||||
|
||||
let inline_asm_func = fx
|
||||
.module
|
||||
.declare_function(asm_name, Linkage::Import, &Signature {
|
||||
call_conv: CallConv::SystemV,
|
||||
params: vec![AbiParam::new(fx.pointer_type)],
|
||||
returns: vec![],
|
||||
})
|
||||
.declare_function(
|
||||
asm_name,
|
||||
Linkage::Import,
|
||||
&Signature {
|
||||
call_conv: CallConv::SystemV,
|
||||
params: vec![AbiParam::new(fx.pointer_type)],
|
||||
returns: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let inline_asm_func = fx.module.declare_func_in_func(inline_asm_func, fx.bcx.func);
|
||||
if fx.clif_comments.enabled() {
|
||||
|
@ -558,9 +558,12 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
(sym::simd_round, types::F64) => "round",
|
||||
_ => unreachable!("{:?}", intrinsic),
|
||||
};
|
||||
fx.lib_call(name, vec![AbiParam::new(lane_ty)], vec![AbiParam::new(lane_ty)], &[
|
||||
lane,
|
||||
])[0]
|
||||
fx.lib_call(
|
||||
name,
|
||||
vec![AbiParam::new(lane_ty)],
|
||||
vec![AbiParam::new(lane_ty)],
|
||||
&[lane],
|
||||
)[0]
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,12 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||
is_primary_cgu: bool,
|
||||
) {
|
||||
let (main_def_id, sigpipe) = match tcx.entry_fn(()) {
|
||||
Some((def_id, entry_ty)) => (def_id, match entry_ty {
|
||||
EntryFnType::Main { sigpipe } => sigpipe,
|
||||
}),
|
||||
Some((def_id, entry_ty)) => (
|
||||
def_id,
|
||||
match entry_ty {
|
||||
EntryFnType::Main { sigpipe } => sigpipe,
|
||||
},
|
||||
),
|
||||
None => return,
|
||||
};
|
||||
|
||||
|
@ -5,11 +5,15 @@ use crate::prelude::*;
|
||||
fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) {
|
||||
let puts = fx
|
||||
.module
|
||||
.declare_function("puts", Linkage::Import, &Signature {
|
||||
call_conv: fx.target_config.default_call_conv,
|
||||
params: vec![AbiParam::new(fx.pointer_type)],
|
||||
returns: vec![AbiParam::new(types::I32)],
|
||||
})
|
||||
.declare_function(
|
||||
"puts",
|
||||
Linkage::Import,
|
||||
&Signature {
|
||||
call_conv: fx.target_config.default_call_conv,
|
||||
params: vec![AbiParam::new(fx.pointer_type)],
|
||||
returns: vec![AbiParam::new(types::I32)],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let puts = fx.module.declare_func_in_func(puts, &mut fx.bcx.func);
|
||||
if fx.clif_comments.enabled() {
|
||||
|
@ -155,14 +155,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||
// NOTE: not sure why, but we have the wrong type here.
|
||||
let int_type = compare_exchange.get_param(2).to_rvalue().get_type();
|
||||
let src = self.context.new_bitcast(self.location, src, int_type);
|
||||
self.context.new_call(self.location, compare_exchange, &[
|
||||
dst,
|
||||
expected,
|
||||
src,
|
||||
weak,
|
||||
order,
|
||||
failure_order,
|
||||
])
|
||||
self.context.new_call(
|
||||
self.location,
|
||||
compare_exchange,
|
||||
&[dst, expected, src, weak, order, failure_order],
|
||||
)
|
||||
}
|
||||
|
||||
pub fn assign(&self, lvalue: LValue<'gcc>, value: RValue<'gcc>) {
|
||||
@ -1076,9 +1073,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
let align = dest.val.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
|
||||
cg_elem.val.store(self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align));
|
||||
|
||||
let next = self.inbounds_gep(self.backend_type(cg_elem.layout), current.to_rvalue(), &[
|
||||
self.const_usize(1),
|
||||
]);
|
||||
let next = self.inbounds_gep(
|
||||
self.backend_type(cg_elem.layout),
|
||||
current.to_rvalue(),
|
||||
&[self.const_usize(1)],
|
||||
);
|
||||
self.llbb().add_assignment(self.location, current, next);
|
||||
self.br(header_bb);
|
||||
|
||||
|
@ -687,11 +687,12 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
|
||||
let field2 = builder.context.new_field(None, args[1].get_type(), "carryResult");
|
||||
let struct_type =
|
||||
builder.context.new_struct_type(None, "addcarryResult", &[field1, field2]);
|
||||
return_value =
|
||||
builder.context.new_struct_constructor(None, struct_type.as_type(), None, &[
|
||||
return_value,
|
||||
last_arg.dereference(None).to_rvalue(),
|
||||
]);
|
||||
return_value = builder.context.new_struct_constructor(
|
||||
None,
|
||||
struct_type.as_type(),
|
||||
None,
|
||||
&[return_value, last_arg.dereference(None).to_rvalue()],
|
||||
);
|
||||
}
|
||||
}
|
||||
"__builtin_ia32_stmxcsr" => {
|
||||
@ -716,11 +717,12 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
|
||||
let field2 = builder.context.new_field(None, return_value.get_type(), "success");
|
||||
let struct_type =
|
||||
builder.context.new_struct_type(None, "rdrand_result", &[field1, field2]);
|
||||
return_value =
|
||||
builder.context.new_struct_constructor(None, struct_type.as_type(), None, &[
|
||||
random_number,
|
||||
success_variable.to_rvalue(),
|
||||
]);
|
||||
return_value = builder.context.new_struct_constructor(
|
||||
None,
|
||||
struct_type.as_type(),
|
||||
None,
|
||||
&[random_number, success_variable.to_rvalue()],
|
||||
);
|
||||
}
|
||||
"fma" => {
|
||||
let f16_type = builder.context.new_c_type(CType::Float16);
|
||||
|
@ -62,11 +62,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
let arg_tys = sig.inputs();
|
||||
|
||||
if name == sym::simd_select_bitmask {
|
||||
require_simd!(arg_tys[1], InvalidMonomorphization::SimdArgument {
|
||||
span,
|
||||
name,
|
||||
ty: arg_tys[1]
|
||||
});
|
||||
require_simd!(
|
||||
arg_tys[1],
|
||||
InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
|
||||
);
|
||||
let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
||||
|
||||
let expected_int_bits = (len.max(8) - 1).next_power_of_two();
|
||||
@ -140,14 +139,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||
|
||||
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
}
|
||||
);
|
||||
require!(
|
||||
bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
|
||||
InvalidMonomorphization::ReturnIntegerType { span, name, ret_ty, out_ty }
|
||||
@ -269,23 +271,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
let lo_nibble =
|
||||
bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &lo_nibble_elements);
|
||||
|
||||
let mask = bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &vec![
|
||||
bx.context
|
||||
.new_rvalue_from_int(
|
||||
bx.u8_type, 0x0f
|
||||
);
|
||||
byte_vector_type_size
|
||||
as _
|
||||
]);
|
||||
let mask = bx.context.new_rvalue_from_vector(
|
||||
None,
|
||||
long_byte_vector_type,
|
||||
&vec![bx.context.new_rvalue_from_int(bx.u8_type, 0x0f); byte_vector_type_size as _],
|
||||
);
|
||||
|
||||
let four_vec = bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &vec![
|
||||
bx.context
|
||||
.new_rvalue_from_int(
|
||||
bx.u8_type, 4
|
||||
);
|
||||
byte_vector_type_size
|
||||
as _
|
||||
]);
|
||||
let four_vec = bx.context.new_rvalue_from_vector(
|
||||
None,
|
||||
long_byte_vector_type,
|
||||
&vec![bx.context.new_rvalue_from_int(bx.u8_type, 4); byte_vector_type_size as _],
|
||||
);
|
||||
|
||||
// Step 2: Byte-swap the input.
|
||||
let swapped = simd_bswap(bx, args[0].immediate());
|
||||
@ -388,21 +384,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||
|
||||
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
require!(out_len == n, InvalidMonomorphization::ReturnLength {
|
||||
span,
|
||||
name,
|
||||
in_len: n,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(in_elem == out_ty, InvalidMonomorphization::ReturnElement {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_ty
|
||||
});
|
||||
require!(
|
||||
out_len == n,
|
||||
InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
|
||||
);
|
||||
require!(
|
||||
in_elem == out_ty,
|
||||
InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
|
||||
);
|
||||
|
||||
let vector = args[2].immediate();
|
||||
|
||||
@ -411,13 +400,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
if name == sym::simd_insert {
|
||||
require!(in_elem == arg_tys[2], InvalidMonomorphization::InsertedType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
out_ty: arg_tys[2]
|
||||
});
|
||||
require!(
|
||||
in_elem == arg_tys[2],
|
||||
InvalidMonomorphization::InsertedType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
out_ty: arg_tys[2]
|
||||
}
|
||||
);
|
||||
let vector = args[0].immediate();
|
||||
let index = args[1].immediate();
|
||||
let value = args[2].immediate();
|
||||
@ -431,13 +423,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
if name == sym::simd_extract {
|
||||
require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == in_elem,
|
||||
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||
);
|
||||
let vector = args[0].immediate();
|
||||
return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue());
|
||||
}
|
||||
@ -445,18 +434,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
if name == sym::simd_select {
|
||||
let m_elem_ty = in_elem;
|
||||
let m_len = in_len;
|
||||
require_simd!(arg_tys[1], InvalidMonomorphization::SimdArgument {
|
||||
span,
|
||||
name,
|
||||
ty: arg_tys[1]
|
||||
});
|
||||
require_simd!(
|
||||
arg_tys[1],
|
||||
InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
|
||||
);
|
||||
let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
||||
require!(m_len == v_len, InvalidMonomorphization::MismatchedLengths {
|
||||
span,
|
||||
name,
|
||||
m_len,
|
||||
v_len
|
||||
});
|
||||
require!(
|
||||
m_len == v_len,
|
||||
InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len }
|
||||
);
|
||||
match *m_elem_ty.kind() {
|
||||
ty::Int(_) => {}
|
||||
_ => return_error!(InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }),
|
||||
@ -468,25 +454,27 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
|
||||
require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
}
|
||||
);
|
||||
|
||||
match *in_elem.kind() {
|
||||
ty::RawPtr(p_ty, _) => {
|
||||
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
|
||||
bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
|
||||
});
|
||||
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
|
||||
span,
|
||||
name,
|
||||
ty: in_elem
|
||||
});
|
||||
require!(
|
||||
metadata.is_unit(),
|
||||
InvalidMonomorphization::CastWidePointer { span, name, ty: in_elem }
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
|
||||
@ -497,11 +485,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
|
||||
bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
|
||||
});
|
||||
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
|
||||
span,
|
||||
name,
|
||||
ty: out_elem
|
||||
});
|
||||
require!(
|
||||
metadata.is_unit(),
|
||||
InvalidMonomorphization::CastWidePointer { span, name, ty: out_elem }
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
|
||||
@ -524,14 +511,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
|
||||
require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
}
|
||||
);
|
||||
|
||||
match *in_elem.kind() {
|
||||
ty::RawPtr(_, _) => {}
|
||||
@ -560,14 +550,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
|
||||
require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
}
|
||||
);
|
||||
|
||||
match *in_elem.kind() {
|
||||
ty::Uint(ty::UintTy::Usize) => {}
|
||||
@ -596,14 +589,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
if name == sym::simd_cast || name == sym::simd_as {
|
||||
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
}
|
||||
);
|
||||
// casting cares about nominal type, not just structural type
|
||||
if in_elem == out_elem {
|
||||
return Ok(args[0].immediate());
|
||||
@ -629,14 +625,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
|
||||
match (in_style, out_style) {
|
||||
(Style::Unsupported, Style::Unsupported) => {
|
||||
require!(false, InvalidMonomorphization::UnsupportedCast {
|
||||
span,
|
||||
name,
|
||||
in_ty,
|
||||
in_elem,
|
||||
ret_ty,
|
||||
out_elem
|
||||
});
|
||||
require!(
|
||||
false,
|
||||
InvalidMonomorphization::UnsupportedCast {
|
||||
span,
|
||||
name,
|
||||
in_ty,
|
||||
in_elem,
|
||||
ret_ty,
|
||||
out_elem
|
||||
}
|
||||
);
|
||||
}
|
||||
_ => return Ok(bx.context.convert_vector(None, args[0].immediate(), llret_ty)),
|
||||
}
|
||||
@ -914,45 +913,47 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
|
||||
// All types must be simd vector types
|
||||
require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
|
||||
require_simd!(arg_tys[1], InvalidMonomorphization::SimdSecond {
|
||||
span,
|
||||
name,
|
||||
ty: arg_tys[1]
|
||||
});
|
||||
require_simd!(arg_tys[2], InvalidMonomorphization::SimdThird {
|
||||
span,
|
||||
name,
|
||||
ty: arg_tys[2]
|
||||
});
|
||||
require_simd!(
|
||||
arg_tys[1],
|
||||
InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
|
||||
);
|
||||
require_simd!(
|
||||
arg_tys[2],
|
||||
InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
|
||||
);
|
||||
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||
|
||||
// Of the same length:
|
||||
let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
||||
let (out_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx());
|
||||
require!(in_len == out_len, InvalidMonomorphization::SecondArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[1],
|
||||
out_len
|
||||
});
|
||||
require!(in_len == out_len2, InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[2],
|
||||
out_len: out_len2
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::SecondArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[1],
|
||||
out_len
|
||||
}
|
||||
);
|
||||
require!(
|
||||
in_len == out_len2,
|
||||
InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[2],
|
||||
out_len: out_len2
|
||||
}
|
||||
);
|
||||
|
||||
// The return type must match the first argument type
|
||||
require!(ret_ty == in_ty, InvalidMonomorphization::ExpectedReturnType {
|
||||
span,
|
||||
name,
|
||||
in_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == in_ty,
|
||||
InvalidMonomorphization::ExpectedReturnType { span, name, in_ty, ret_ty }
|
||||
);
|
||||
|
||||
// This counts how many pointers
|
||||
fn ptr_count(t: Ty<'_>) -> usize {
|
||||
@ -979,15 +980,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
(ptr_count(element_ty1), non_ptr(element_ty1))
|
||||
}
|
||||
_ => {
|
||||
require!(false, InvalidMonomorphization::ExpectedElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: element_ty1,
|
||||
second_arg: arg_tys[1],
|
||||
in_elem,
|
||||
in_ty,
|
||||
mutability: ExpectedPointerMutability::Not,
|
||||
});
|
||||
require!(
|
||||
false,
|
||||
InvalidMonomorphization::ExpectedElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: element_ty1,
|
||||
second_arg: arg_tys[1],
|
||||
in_elem,
|
||||
in_ty,
|
||||
mutability: ExpectedPointerMutability::Not,
|
||||
}
|
||||
);
|
||||
unreachable!();
|
||||
}
|
||||
};
|
||||
@ -1000,12 +1004,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
match *element_ty2.kind() {
|
||||
ty::Int(_) => (),
|
||||
_ => {
|
||||
require!(false, InvalidMonomorphization::ThirdArgElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: element_ty2,
|
||||
third_arg: arg_tys[2]
|
||||
});
|
||||
require!(
|
||||
false,
|
||||
InvalidMonomorphization::ThirdArgElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: element_ty2,
|
||||
third_arg: arg_tys[2]
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1029,36 +1036,40 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
|
||||
// All types must be simd vector types
|
||||
require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
|
||||
require_simd!(arg_tys[1], InvalidMonomorphization::SimdSecond {
|
||||
span,
|
||||
name,
|
||||
ty: arg_tys[1]
|
||||
});
|
||||
require_simd!(arg_tys[2], InvalidMonomorphization::SimdThird {
|
||||
span,
|
||||
name,
|
||||
ty: arg_tys[2]
|
||||
});
|
||||
require_simd!(
|
||||
arg_tys[1],
|
||||
InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
|
||||
);
|
||||
require_simd!(
|
||||
arg_tys[2],
|
||||
InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
|
||||
);
|
||||
|
||||
// Of the same length:
|
||||
let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
||||
let (element_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx());
|
||||
require!(in_len == element_len1, InvalidMonomorphization::SecondArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[1],
|
||||
out_len: element_len1
|
||||
});
|
||||
require!(in_len == element_len2, InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[2],
|
||||
out_len: element_len2
|
||||
});
|
||||
require!(
|
||||
in_len == element_len1,
|
||||
InvalidMonomorphization::SecondArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[1],
|
||||
out_len: element_len1
|
||||
}
|
||||
);
|
||||
require!(
|
||||
in_len == element_len2,
|
||||
InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[2],
|
||||
out_len: element_len2
|
||||
}
|
||||
);
|
||||
|
||||
// This counts how many pointers
|
||||
fn ptr_count(t: Ty<'_>) -> usize {
|
||||
@ -1086,15 +1097,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
(ptr_count(element_ty1), non_ptr(element_ty1))
|
||||
}
|
||||
_ => {
|
||||
require!(false, InvalidMonomorphization::ExpectedElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: element_ty1,
|
||||
second_arg: arg_tys[1],
|
||||
in_elem,
|
||||
in_ty,
|
||||
mutability: ExpectedPointerMutability::Mut,
|
||||
});
|
||||
require!(
|
||||
false,
|
||||
InvalidMonomorphization::ExpectedElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: element_ty1,
|
||||
second_arg: arg_tys[1],
|
||||
in_elem,
|
||||
in_ty,
|
||||
mutability: ExpectedPointerMutability::Mut,
|
||||
}
|
||||
);
|
||||
unreachable!();
|
||||
}
|
||||
};
|
||||
@ -1106,12 +1120,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
match *element_ty2.kind() {
|
||||
ty::Int(_) => (),
|
||||
_ => {
|
||||
require!(false, InvalidMonomorphization::ThirdArgElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: element_ty2,
|
||||
third_arg: arg_tys[2]
|
||||
});
|
||||
require!(
|
||||
false,
|
||||
InvalidMonomorphization::ThirdArgElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: element_ty2,
|
||||
third_arg: arg_tys[2]
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1278,13 +1295,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
($name:ident : $vec_op:expr, $float_reduce:ident, $ordered:expr, $op:ident,
|
||||
$identity:expr) => {
|
||||
if name == sym::$name {
|
||||
require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == in_elem,
|
||||
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||
);
|
||||
return match *in_elem.kind() {
|
||||
ty::Int(_) | ty::Uint(_) => {
|
||||
let r = bx.vector_reduce_op(args[0].immediate(), $vec_op);
|
||||
@ -1350,13 +1364,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
macro_rules! minmax_red {
|
||||
($name:ident: $int_red:ident, $float_red:ident) => {
|
||||
if name == sym::$name {
|
||||
require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == in_elem,
|
||||
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||
);
|
||||
return match *in_elem.kind() {
|
||||
ty::Int(_) | ty::Uint(_) => Ok(bx.$int_red(args[0].immediate())),
|
||||
ty::Float(_) => Ok(bx.$float_red(args[0].immediate())),
|
||||
@ -1380,13 +1391,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
($name:ident : $op:expr, $boolean:expr) => {
|
||||
if name == sym::$name {
|
||||
let input = if !$boolean {
|
||||
require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == in_elem,
|
||||
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||
);
|
||||
args[0].immediate()
|
||||
} else {
|
||||
match *in_elem.kind() {
|
||||
|
@ -447,11 +447,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||
// LLVM also rejects full range.
|
||||
&& !scalar.is_always_valid(cx)
|
||||
{
|
||||
attributes::apply_to_llfn(llfn, idx, &[llvm::CreateRangeAttr(
|
||||
cx.llcx,
|
||||
scalar.size(cx),
|
||||
scalar.valid_range(cx),
|
||||
)]);
|
||||
attributes::apply_to_llfn(
|
||||
llfn,
|
||||
idx,
|
||||
&[llvm::CreateRangeAttr(cx.llcx, scalar.size(cx), scalar.valid_range(cx))],
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -471,10 +471,14 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||
);
|
||||
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[sret]);
|
||||
if cx.sess().opts.optimize != config::OptLevel::No {
|
||||
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[
|
||||
llvm::AttributeKind::Writable.create_attr(cx.llcx),
|
||||
llvm::AttributeKind::DeadOnUnwind.create_attr(cx.llcx),
|
||||
]);
|
||||
attributes::apply_to_llfn(
|
||||
llfn,
|
||||
llvm::AttributePlace::Argument(i),
|
||||
&[
|
||||
llvm::AttributeKind::Writable.create_attr(cx.llcx),
|
||||
llvm::AttributeKind::DeadOnUnwind.create_attr(cx.llcx),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
PassMode::Cast { cast, pad_i32: _ } => {
|
||||
@ -592,9 +596,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||
bx.cx.llcx,
|
||||
bx.cx.type_array(bx.cx.type_i8(), arg.layout.size.bytes()),
|
||||
);
|
||||
attributes::apply_to_callsite(callsite, llvm::AttributePlace::Argument(i), &[
|
||||
byval,
|
||||
]);
|
||||
attributes::apply_to_callsite(
|
||||
callsite,
|
||||
llvm::AttributePlace::Argument(i),
|
||||
&[byval],
|
||||
);
|
||||
}
|
||||
PassMode::Direct(attrs)
|
||||
| PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => {
|
||||
@ -626,9 +632,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||
// This will probably get ignored on all targets but those supporting the TrustZone-M
|
||||
// extension (thumbv8m targets).
|
||||
let cmse_nonsecure_call = llvm::CreateAttrString(bx.cx.llcx, "cmse_nonsecure_call");
|
||||
attributes::apply_to_callsite(callsite, llvm::AttributePlace::Function, &[
|
||||
cmse_nonsecure_call,
|
||||
]);
|
||||
attributes::apply_to_callsite(
|
||||
callsite,
|
||||
llvm::AttributePlace::Function,
|
||||
&[cmse_nonsecure_call],
|
||||
);
|
||||
}
|
||||
|
||||
// Some intrinsics require that an elementtype attribute (with the pointee type of a
|
||||
|
@ -291,20 +291,26 @@ pub(crate) fn differentiate<'ll>(
|
||||
let name = item.source.clone();
|
||||
let fn_def: Option<&llvm::Value> = cx.get_function(&name);
|
||||
let Some(fn_def) = fn_def else {
|
||||
return Err(llvm_err(diag_handler.handle(), LlvmError::PrepareAutoDiff {
|
||||
src: item.source.clone(),
|
||||
target: item.target.clone(),
|
||||
error: "could not find source function".to_owned(),
|
||||
}));
|
||||
return Err(llvm_err(
|
||||
diag_handler.handle(),
|
||||
LlvmError::PrepareAutoDiff {
|
||||
src: item.source.clone(),
|
||||
target: item.target.clone(),
|
||||
error: "could not find source function".to_owned(),
|
||||
},
|
||||
));
|
||||
};
|
||||
debug!(?item.target);
|
||||
let fn_target: Option<&llvm::Value> = cx.get_function(&item.target);
|
||||
let Some(fn_target) = fn_target else {
|
||||
return Err(llvm_err(diag_handler.handle(), LlvmError::PrepareAutoDiff {
|
||||
src: item.source.clone(),
|
||||
target: item.target.clone(),
|
||||
error: "could not find target function".to_owned(),
|
||||
}));
|
||||
return Err(llvm_err(
|
||||
diag_handler.handle(),
|
||||
LlvmError::PrepareAutoDiff {
|
||||
src: item.source.clone(),
|
||||
target: item.target.clone(),
|
||||
error: "could not find target function".to_owned(),
|
||||
},
|
||||
));
|
||||
};
|
||||
|
||||
generate_enzyme_call(&cx, fn_def, fn_target, item.attrs.clone());
|
||||
|
@ -548,14 +548,17 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
let scope = namespace::item_namespace(cx, DefId {
|
||||
krate: instance.def_id().krate,
|
||||
index: cx
|
||||
.tcx
|
||||
.def_key(instance.def_id())
|
||||
.parent
|
||||
.expect("get_containing_scope: missing parent?"),
|
||||
});
|
||||
let scope = namespace::item_namespace(
|
||||
cx,
|
||||
DefId {
|
||||
krate: instance.def_id().krate,
|
||||
index: cx
|
||||
.tcx
|
||||
.def_key(instance.def_id())
|
||||
.parent
|
||||
.expect("get_containing_scope: missing parent?"),
|
||||
},
|
||||
);
|
||||
(scope, false)
|
||||
}
|
||||
}
|
||||
|
@ -333,12 +333,15 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
sym::prefetch_write_instruction => (1, 0),
|
||||
_ => bug!(),
|
||||
};
|
||||
self.call_intrinsic("llvm.prefetch", &[
|
||||
args[0].immediate(),
|
||||
self.const_i32(rw),
|
||||
args[1].immediate(),
|
||||
self.const_i32(cache_type),
|
||||
])
|
||||
self.call_intrinsic(
|
||||
"llvm.prefetch",
|
||||
&[
|
||||
args[0].immediate(),
|
||||
self.const_i32(rw),
|
||||
args[1].immediate(),
|
||||
self.const_i32(cache_type),
|
||||
],
|
||||
)
|
||||
}
|
||||
sym::carrying_mul_add => {
|
||||
let (size, signed) = fn_args.type_at(0).int_size_and_signed(self.tcx);
|
||||
@ -396,10 +399,10 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
match name {
|
||||
sym::ctlz | sym::cttz => {
|
||||
let y = self.const_bool(false);
|
||||
let ret = self.call_intrinsic(&format!("llvm.{name}.i{width}"), &[
|
||||
args[0].immediate(),
|
||||
y,
|
||||
]);
|
||||
let ret = self.call_intrinsic(
|
||||
&format!("llvm.{name}.i{width}"),
|
||||
&[args[0].immediate(), y],
|
||||
);
|
||||
|
||||
self.intcast(ret, llret_ty, false)
|
||||
}
|
||||
@ -416,24 +419,26 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
self.intcast(ret, llret_ty, false)
|
||||
}
|
||||
sym::ctpop => {
|
||||
let ret = self.call_intrinsic(&format!("llvm.ctpop.i{width}"), &[
|
||||
args[0].immediate()
|
||||
]);
|
||||
let ret = self.call_intrinsic(
|
||||
&format!("llvm.ctpop.i{width}"),
|
||||
&[args[0].immediate()],
|
||||
);
|
||||
self.intcast(ret, llret_ty, false)
|
||||
}
|
||||
sym::bswap => {
|
||||
if width == 8 {
|
||||
args[0].immediate() // byte swap a u8/i8 is just a no-op
|
||||
} else {
|
||||
self.call_intrinsic(&format!("llvm.bswap.i{width}"), &[
|
||||
args[0].immediate()
|
||||
])
|
||||
self.call_intrinsic(
|
||||
&format!("llvm.bswap.i{width}"),
|
||||
&[args[0].immediate()],
|
||||
)
|
||||
}
|
||||
}
|
||||
sym::bitreverse => self
|
||||
.call_intrinsic(&format!("llvm.bitreverse.i{width}"), &[
|
||||
args[0].immediate()
|
||||
]),
|
||||
sym::bitreverse => self.call_intrinsic(
|
||||
&format!("llvm.bitreverse.i{width}"),
|
||||
&[args[0].immediate()],
|
||||
),
|
||||
sym::rotate_left | sym::rotate_right => {
|
||||
let is_left = name == sym::rotate_left;
|
||||
let val = args[0].immediate();
|
||||
@ -500,11 +505,10 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
|
||||
sym::compare_bytes => {
|
||||
// Here we assume that the `memcmp` provided by the target is a NOP for size 0.
|
||||
let cmp = self.call_intrinsic("memcmp", &[
|
||||
args[0].immediate(),
|
||||
args[1].immediate(),
|
||||
args[2].immediate(),
|
||||
]);
|
||||
let cmp = self.call_intrinsic(
|
||||
"memcmp",
|
||||
&[args[0].immediate(), args[1].immediate(), args[2].immediate()],
|
||||
);
|
||||
// Some targets have `memcmp` returning `i16`, but the intrinsic is always `i32`.
|
||||
self.sext(cmp, self.type_ix(32))
|
||||
}
|
||||
@ -1305,14 +1309,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
if let Some(cmp_op) = comparison {
|
||||
let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
|
||||
|
||||
require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
}
|
||||
);
|
||||
require!(
|
||||
bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
|
||||
InvalidMonomorphization::ReturnIntegerType { span, name, ret_ty, out_ty }
|
||||
@ -1333,21 +1340,14 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
let n = idx.len() as u64;
|
||||
|
||||
let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
|
||||
require!(out_len == n, InvalidMonomorphization::ReturnLength {
|
||||
span,
|
||||
name,
|
||||
in_len: n,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(in_elem == out_ty, InvalidMonomorphization::ReturnElement {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_ty
|
||||
});
|
||||
require!(
|
||||
out_len == n,
|
||||
InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
|
||||
);
|
||||
require!(
|
||||
in_elem == out_ty,
|
||||
InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
|
||||
);
|
||||
|
||||
let total_len = in_len * 2;
|
||||
|
||||
@ -1392,21 +1392,14 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
};
|
||||
|
||||
let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
|
||||
require!(out_len == n, InvalidMonomorphization::ReturnLength {
|
||||
span,
|
||||
name,
|
||||
in_len: n,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(in_elem == out_ty, InvalidMonomorphization::ReturnElement {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_ty
|
||||
});
|
||||
require!(
|
||||
out_len == n,
|
||||
InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
|
||||
);
|
||||
require!(
|
||||
in_elem == out_ty,
|
||||
InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
|
||||
);
|
||||
|
||||
let total_len = u128::from(in_len) * 2;
|
||||
|
||||
@ -1431,13 +1424,16 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
}
|
||||
|
||||
if name == sym::simd_insert {
|
||||
require!(in_elem == arg_tys[2], InvalidMonomorphization::InsertedType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
out_ty: arg_tys[2]
|
||||
});
|
||||
require!(
|
||||
in_elem == arg_tys[2],
|
||||
InvalidMonomorphization::InsertedType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
out_ty: arg_tys[2]
|
||||
}
|
||||
);
|
||||
let idx = bx
|
||||
.const_to_opt_u128(args[1].immediate(), false)
|
||||
.expect("typeck should have ensure that this is a const");
|
||||
@ -1456,13 +1452,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
));
|
||||
}
|
||||
if name == sym::simd_extract {
|
||||
require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == in_elem,
|
||||
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||
);
|
||||
let idx = bx
|
||||
.const_to_opt_u128(args[1].immediate(), false)
|
||||
.expect("typeck should have ensure that this is a const");
|
||||
@ -1481,18 +1474,14 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
let m_elem_ty = in_elem;
|
||||
let m_len = in_len;
|
||||
let (v_len, _) = require_simd!(arg_tys[1], SimdArgument);
|
||||
require!(m_len == v_len, InvalidMonomorphization::MismatchedLengths {
|
||||
span,
|
||||
name,
|
||||
m_len,
|
||||
v_len
|
||||
});
|
||||
let in_elem_bitwidth =
|
||||
require_int_ty!(m_elem_ty.kind(), InvalidMonomorphization::MaskType {
|
||||
span,
|
||||
name,
|
||||
ty: m_elem_ty
|
||||
});
|
||||
require!(
|
||||
m_len == v_len,
|
||||
InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len }
|
||||
);
|
||||
let in_elem_bitwidth = require_int_ty!(
|
||||
m_elem_ty.kind(),
|
||||
InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }
|
||||
);
|
||||
let m_i1s = vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, m_len);
|
||||
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
|
||||
}
|
||||
@ -1510,13 +1499,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
let expected_bytes = in_len.div_ceil(8);
|
||||
|
||||
// Integer vector <i{in_bitwidth} x in_len>:
|
||||
let in_elem_bitwidth =
|
||||
require_int_or_uint_ty!(in_elem.kind(), InvalidMonomorphization::VectorArgument {
|
||||
span,
|
||||
name,
|
||||
in_ty,
|
||||
in_elem
|
||||
});
|
||||
let in_elem_bitwidth = require_int_or_uint_ty!(
|
||||
in_elem.kind(),
|
||||
InvalidMonomorphization::VectorArgument { span, name, in_ty, in_elem }
|
||||
);
|
||||
|
||||
let i1xn = vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, in_len);
|
||||
// Bitcast <i1 x N> to iN:
|
||||
@ -1698,30 +1684,34 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
require_simd!(ret_ty, SimdReturn);
|
||||
|
||||
// Of the same length:
|
||||
require!(in_len == out_len, InvalidMonomorphization::SecondArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[1],
|
||||
out_len
|
||||
});
|
||||
require!(in_len == out_len2, InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[2],
|
||||
out_len: out_len2
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::SecondArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[1],
|
||||
out_len
|
||||
}
|
||||
);
|
||||
require!(
|
||||
in_len == out_len2,
|
||||
InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[2],
|
||||
out_len: out_len2
|
||||
}
|
||||
);
|
||||
|
||||
// The return type must match the first argument type
|
||||
require!(ret_ty == in_ty, InvalidMonomorphization::ExpectedReturnType {
|
||||
span,
|
||||
name,
|
||||
in_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == in_ty,
|
||||
InvalidMonomorphization::ExpectedReturnType { span, name, in_ty, ret_ty }
|
||||
);
|
||||
|
||||
require!(
|
||||
matches!(
|
||||
@ -1739,13 +1729,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
}
|
||||
);
|
||||
|
||||
let mask_elem_bitwidth =
|
||||
require_int_ty!(element_ty2.kind(), InvalidMonomorphization::ThirdArgElementType {
|
||||
let mask_elem_bitwidth = require_int_ty!(
|
||||
element_ty2.kind(),
|
||||
InvalidMonomorphization::ThirdArgElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: element_ty2,
|
||||
third_arg: arg_tys[2]
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Alignment of T, must be a constant integer value:
|
||||
let alignment_ty = bx.type_i32();
|
||||
@ -1805,22 +1797,23 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
require_simd!(ret_ty, SimdReturn);
|
||||
|
||||
// Of the same length:
|
||||
require!(values_len == mask_len, InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len: mask_len,
|
||||
in_ty: mask_ty,
|
||||
arg_ty: values_ty,
|
||||
out_len: values_len
|
||||
});
|
||||
require!(
|
||||
values_len == mask_len,
|
||||
InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len: mask_len,
|
||||
in_ty: mask_ty,
|
||||
arg_ty: values_ty,
|
||||
out_len: values_len
|
||||
}
|
||||
);
|
||||
|
||||
// The return type must match the last argument type
|
||||
require!(ret_ty == values_ty, InvalidMonomorphization::ExpectedReturnType {
|
||||
span,
|
||||
name,
|
||||
in_ty: values_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == values_ty,
|
||||
InvalidMonomorphization::ExpectedReturnType { span, name, in_ty: values_ty, ret_ty }
|
||||
);
|
||||
|
||||
require!(
|
||||
matches!(
|
||||
@ -1838,13 +1831,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
}
|
||||
);
|
||||
|
||||
let m_elem_bitwidth =
|
||||
require_int_ty!(mask_elem.kind(), InvalidMonomorphization::ThirdArgElementType {
|
||||
let m_elem_bitwidth = require_int_ty!(
|
||||
mask_elem.kind(),
|
||||
InvalidMonomorphization::ThirdArgElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: values_elem,
|
||||
third_arg: mask_ty,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len);
|
||||
let mask_ty = bx.type_vector(bx.type_i1(), mask_len);
|
||||
@ -1896,14 +1891,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
let (values_len, values_elem) = require_simd!(values_ty, SimdThird);
|
||||
|
||||
// Of the same length:
|
||||
require!(values_len == mask_len, InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len: mask_len,
|
||||
in_ty: mask_ty,
|
||||
arg_ty: values_ty,
|
||||
out_len: values_len
|
||||
});
|
||||
require!(
|
||||
values_len == mask_len,
|
||||
InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len: mask_len,
|
||||
in_ty: mask_ty,
|
||||
arg_ty: values_ty,
|
||||
out_len: values_len
|
||||
}
|
||||
);
|
||||
|
||||
// The second argument must be a mutable pointer type matching the element type
|
||||
require!(
|
||||
@ -1923,13 +1921,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
}
|
||||
);
|
||||
|
||||
let m_elem_bitwidth =
|
||||
require_int_ty!(mask_elem.kind(), InvalidMonomorphization::ThirdArgElementType {
|
||||
let m_elem_bitwidth = require_int_ty!(
|
||||
mask_elem.kind(),
|
||||
InvalidMonomorphization::ThirdArgElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: values_elem,
|
||||
third_arg: mask_ty,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len);
|
||||
let mask_ty = bx.type_vector(bx.type_i1(), mask_len);
|
||||
@ -1976,22 +1976,28 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
let (element_len2, element_ty2) = require_simd!(arg_tys[2], SimdThird);
|
||||
|
||||
// Of the same length:
|
||||
require!(in_len == element_len1, InvalidMonomorphization::SecondArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[1],
|
||||
out_len: element_len1
|
||||
});
|
||||
require!(in_len == element_len2, InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[2],
|
||||
out_len: element_len2
|
||||
});
|
||||
require!(
|
||||
in_len == element_len1,
|
||||
InvalidMonomorphization::SecondArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[1],
|
||||
out_len: element_len1
|
||||
}
|
||||
);
|
||||
require!(
|
||||
in_len == element_len2,
|
||||
InvalidMonomorphization::ThirdArgumentLength {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
arg_ty: arg_tys[2],
|
||||
out_len: element_len2
|
||||
}
|
||||
);
|
||||
|
||||
require!(
|
||||
matches!(
|
||||
@ -2011,13 +2017,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
);
|
||||
|
||||
// The element type of the third argument must be a signed integer type of any width:
|
||||
let mask_elem_bitwidth =
|
||||
require_int_ty!(element_ty2.kind(), InvalidMonomorphization::ThirdArgElementType {
|
||||
let mask_elem_bitwidth = require_int_ty!(
|
||||
element_ty2.kind(),
|
||||
InvalidMonomorphization::ThirdArgElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: element_ty2,
|
||||
third_arg: arg_tys[2]
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Alignment of T, must be a constant integer value:
|
||||
let alignment_ty = bx.type_i32();
|
||||
@ -2058,13 +2066,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
($name:ident : $integer_reduce:ident, $float_reduce:ident, $ordered:expr, $op:ident,
|
||||
$identity:expr) => {
|
||||
if name == sym::$name {
|
||||
require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == in_elem,
|
||||
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||
);
|
||||
return match in_elem.kind() {
|
||||
ty::Int(_) | ty::Uint(_) => {
|
||||
let r = bx.$integer_reduce(args[0].immediate());
|
||||
@ -2133,13 +2138,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
macro_rules! minmax_red {
|
||||
($name:ident: $int_red:ident, $float_red:ident) => {
|
||||
if name == sym::$name {
|
||||
require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == in_elem,
|
||||
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||
);
|
||||
return match in_elem.kind() {
|
||||
ty::Int(_i) => Ok(bx.$int_red(args[0].immediate(), true)),
|
||||
ty::Uint(_u) => Ok(bx.$int_red(args[0].immediate(), false)),
|
||||
@ -2164,13 +2166,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
($name:ident : $red:ident, $boolean:expr) => {
|
||||
if name == sym::$name {
|
||||
let input = if !$boolean {
|
||||
require!(ret_ty == in_elem, InvalidMonomorphization::ReturnType {
|
||||
span,
|
||||
name,
|
||||
in_elem,
|
||||
in_ty,
|
||||
ret_ty
|
||||
});
|
||||
require!(
|
||||
ret_ty == in_elem,
|
||||
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||
);
|
||||
args[0].immediate()
|
||||
} else {
|
||||
let bitwidth = match in_elem.kind() {
|
||||
@ -2218,25 +2217,27 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
|
||||
if name == sym::simd_cast_ptr {
|
||||
let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
|
||||
require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
}
|
||||
);
|
||||
|
||||
match in_elem.kind() {
|
||||
ty::RawPtr(p_ty, _) => {
|
||||
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
|
||||
bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
|
||||
});
|
||||
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
|
||||
span,
|
||||
name,
|
||||
ty: in_elem
|
||||
});
|
||||
require!(
|
||||
metadata.is_unit(),
|
||||
InvalidMonomorphization::CastWidePointer { span, name, ty: in_elem }
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
|
||||
@ -2247,11 +2248,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
|
||||
bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
|
||||
});
|
||||
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
|
||||
span,
|
||||
name,
|
||||
ty: out_elem
|
||||
});
|
||||
require!(
|
||||
metadata.is_unit(),
|
||||
InvalidMonomorphization::CastWidePointer { span, name, ty: out_elem }
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
|
||||
@ -2263,14 +2263,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
|
||||
if name == sym::simd_expose_provenance {
|
||||
let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
|
||||
require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
}
|
||||
);
|
||||
|
||||
match in_elem.kind() {
|
||||
ty::RawPtr(_, _) => {}
|
||||
@ -2288,14 +2291,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
|
||||
if name == sym::simd_with_exposed_provenance {
|
||||
let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
|
||||
require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
}
|
||||
);
|
||||
|
||||
match in_elem.kind() {
|
||||
ty::Uint(ty::UintTy::Usize) => {}
|
||||
@ -2313,14 +2319,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
|
||||
if name == sym::simd_cast || name == sym::simd_as {
|
||||
let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
|
||||
require!(in_len == out_len, InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
});
|
||||
require!(
|
||||
in_len == out_len,
|
||||
InvalidMonomorphization::ReturnLengthInputType {
|
||||
span,
|
||||
name,
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
}
|
||||
);
|
||||
// casting cares about nominal type, not just structural type
|
||||
if in_elem == out_elem {
|
||||
return Ok(args[0].immediate());
|
||||
|
@ -414,10 +414,10 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
|
||||
let member_path = archive_path.parent().unwrap().join(Path::new(&file_name));
|
||||
self.entries.push((file_name.into_bytes(), ArchiveEntry::File(member_path)));
|
||||
} else {
|
||||
self.entries.push((file_name.into_bytes(), ArchiveEntry::FromArchive {
|
||||
archive_index,
|
||||
file_range: entry.file_range(),
|
||||
}));
|
||||
self.entries.push((
|
||||
file_name.into_bytes(),
|
||||
ArchiveEntry::FromArchive { archive_index, file_range: entry.file_range() },
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,23 +10,22 @@ fn test_rpaths_to_args() {
|
||||
#[test]
|
||||
fn test_xlinker() {
|
||||
let mut cmd = Command::new("foo");
|
||||
convert_link_args_to_cc_args(&mut cmd, &[
|
||||
"arg1",
|
||||
"arg2",
|
||||
"arg3,with,comma",
|
||||
"arg4,with,comma",
|
||||
"arg5",
|
||||
"arg6,with,comma",
|
||||
]);
|
||||
convert_link_args_to_cc_args(
|
||||
&mut cmd,
|
||||
&["arg1", "arg2", "arg3,with,comma", "arg4,with,comma", "arg5", "arg6,with,comma"],
|
||||
);
|
||||
|
||||
assert_eq!(cmd.get_args(), [
|
||||
OsStr::new("-Wl,arg1,arg2"),
|
||||
OsStr::new("-Xlinker"),
|
||||
OsStr::new("arg3,with,comma"),
|
||||
OsStr::new("-Xlinker"),
|
||||
OsStr::new("arg4,with,comma"),
|
||||
OsStr::new("-Wl,arg5"),
|
||||
OsStr::new("-Xlinker"),
|
||||
OsStr::new("arg6,with,comma"),
|
||||
]);
|
||||
assert_eq!(
|
||||
cmd.get_args(),
|
||||
[
|
||||
OsStr::new("-Wl,arg1,arg2"),
|
||||
OsStr::new("-Xlinker"),
|
||||
OsStr::new("arg3,with,comma"),
|
||||
OsStr::new("-Xlinker"),
|
||||
OsStr::new("arg4,with,comma"),
|
||||
OsStr::new("-Wl,arg5"),
|
||||
OsStr::new("-Xlinker"),
|
||||
OsStr::new("arg6,with,comma"),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -704,13 +704,17 @@ pub fn create_metadata_file_for_wasm(sess: &Session, data: &[u8], section_name:
|
||||
let mut imports = wasm_encoder::ImportSection::new();
|
||||
|
||||
if sess.target.pointer_width == 64 {
|
||||
imports.import("env", "__linear_memory", wasm_encoder::MemoryType {
|
||||
minimum: 0,
|
||||
maximum: None,
|
||||
memory64: true,
|
||||
shared: false,
|
||||
page_size_log2: None,
|
||||
});
|
||||
imports.import(
|
||||
"env",
|
||||
"__linear_memory",
|
||||
wasm_encoder::MemoryType {
|
||||
minimum: 0,
|
||||
maximum: None,
|
||||
memory64: true,
|
||||
shared: false,
|
||||
page_size_log2: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if imports.len() > 0 {
|
||||
|
@ -140,11 +140,14 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
|
||||
.into();
|
||||
|
||||
if let Some(id) = tcx.proc_macro_decls_static(()) {
|
||||
reachable_non_generics.insert(id.to_def_id(), SymbolExportInfo {
|
||||
level: SymbolExportLevel::C,
|
||||
kind: SymbolExportKind::Data,
|
||||
used: false,
|
||||
});
|
||||
reachable_non_generics.insert(
|
||||
id.to_def_id(),
|
||||
SymbolExportInfo {
|
||||
level: SymbolExportLevel::C,
|
||||
kind: SymbolExportKind::Data,
|
||||
used: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
reachable_non_generics
|
||||
@ -185,11 +188,14 @@ fn exported_symbols_provider_local(
|
||||
if !tcx.sess.target.dll_tls_export {
|
||||
symbols.extend(sorted.iter().filter_map(|(&def_id, &info)| {
|
||||
tcx.needs_thread_local_shim(def_id).then(|| {
|
||||
(ExportedSymbol::ThreadLocalShim(def_id), SymbolExportInfo {
|
||||
level: info.level,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: info.used,
|
||||
})
|
||||
(
|
||||
ExportedSymbol::ThreadLocalShim(def_id),
|
||||
SymbolExportInfo {
|
||||
level: info.level,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: info.used,
|
||||
},
|
||||
)
|
||||
})
|
||||
}))
|
||||
}
|
||||
@ -198,11 +204,14 @@ fn exported_symbols_provider_local(
|
||||
let exported_symbol =
|
||||
ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref()));
|
||||
|
||||
symbols.push((exported_symbol, SymbolExportInfo {
|
||||
level: SymbolExportLevel::C,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: false,
|
||||
}));
|
||||
symbols.push((
|
||||
exported_symbol,
|
||||
SymbolExportInfo {
|
||||
level: SymbolExportLevel::C,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: false,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
// Mark allocator shim symbols as exported only if they were generated.
|
||||
@ -214,20 +223,26 @@ fn exported_symbols_provider_local(
|
||||
{
|
||||
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
|
||||
|
||||
symbols.push((exported_symbol, SymbolExportInfo {
|
||||
level: SymbolExportLevel::Rust,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: false,
|
||||
}));
|
||||
symbols.push((
|
||||
exported_symbol,
|
||||
SymbolExportInfo {
|
||||
level: SymbolExportLevel::Rust,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: false,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
let exported_symbol =
|
||||
ExportedSymbol::NoDefId(SymbolName::new(tcx, NO_ALLOC_SHIM_IS_UNSTABLE));
|
||||
symbols.push((exported_symbol, SymbolExportInfo {
|
||||
level: SymbolExportLevel::Rust,
|
||||
kind: SymbolExportKind::Data,
|
||||
used: false,
|
||||
}))
|
||||
symbols.push((
|
||||
exported_symbol,
|
||||
SymbolExportInfo {
|
||||
level: SymbolExportLevel::Rust,
|
||||
kind: SymbolExportKind::Data,
|
||||
used: false,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() {
|
||||
@ -239,11 +254,14 @@ fn exported_symbols_provider_local(
|
||||
|
||||
symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| {
|
||||
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
|
||||
(exported_symbol, SymbolExportInfo {
|
||||
level: SymbolExportLevel::C,
|
||||
kind: SymbolExportKind::Data,
|
||||
used: false,
|
||||
})
|
||||
(
|
||||
exported_symbol,
|
||||
SymbolExportInfo {
|
||||
level: SymbolExportLevel::C,
|
||||
kind: SymbolExportKind::Data,
|
||||
used: false,
|
||||
},
|
||||
)
|
||||
}));
|
||||
}
|
||||
|
||||
@ -261,11 +279,14 @@ fn exported_symbols_provider_local(
|
||||
|
||||
symbols.extend(msan_weak_symbols.into_iter().map(|sym| {
|
||||
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
|
||||
(exported_symbol, SymbolExportInfo {
|
||||
level: SymbolExportLevel::C,
|
||||
kind: SymbolExportKind::Data,
|
||||
used: false,
|
||||
})
|
||||
(
|
||||
exported_symbol,
|
||||
SymbolExportInfo {
|
||||
level: SymbolExportLevel::C,
|
||||
kind: SymbolExportKind::Data,
|
||||
used: false,
|
||||
},
|
||||
)
|
||||
}));
|
||||
}
|
||||
|
||||
@ -275,11 +296,14 @@ fn exported_symbols_provider_local(
|
||||
let symbol_name = metadata_symbol_name(tcx);
|
||||
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
|
||||
|
||||
symbols.push((exported_symbol, SymbolExportInfo {
|
||||
level: SymbolExportLevel::C,
|
||||
kind: SymbolExportKind::Data,
|
||||
used: true,
|
||||
}));
|
||||
symbols.push((
|
||||
exported_symbol,
|
||||
SymbolExportInfo {
|
||||
level: SymbolExportLevel::C,
|
||||
kind: SymbolExportKind::Data,
|
||||
used: true,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
if tcx.local_crate_exports_generics() {
|
||||
@ -325,21 +349,27 @@ fn exported_symbols_provider_local(
|
||||
MonoItem::Fn(Instance { def: InstanceKind::Item(def), args }) => {
|
||||
if args.non_erasable_generics().next().is_some() {
|
||||
let symbol = ExportedSymbol::Generic(def, args);
|
||||
symbols.push((symbol, SymbolExportInfo {
|
||||
level: SymbolExportLevel::Rust,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: false,
|
||||
}));
|
||||
symbols.push((
|
||||
symbol,
|
||||
SymbolExportInfo {
|
||||
level: SymbolExportLevel::Rust,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: false,
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
MonoItem::Fn(Instance { def: InstanceKind::DropGlue(_, Some(ty)), args }) => {
|
||||
// A little sanity-check
|
||||
assert_eq!(args.non_erasable_generics().next(), Some(GenericArgKind::Type(ty)));
|
||||
symbols.push((ExportedSymbol::DropGlue(ty), SymbolExportInfo {
|
||||
level: SymbolExportLevel::Rust,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: false,
|
||||
}));
|
||||
symbols.push((
|
||||
ExportedSymbol::DropGlue(ty),
|
||||
SymbolExportInfo {
|
||||
level: SymbolExportLevel::Rust,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: false,
|
||||
},
|
||||
));
|
||||
}
|
||||
MonoItem::Fn(Instance {
|
||||
def: InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)),
|
||||
@ -347,11 +377,14 @@ fn exported_symbols_provider_local(
|
||||
}) => {
|
||||
// A little sanity-check
|
||||
assert_eq!(args.non_erasable_generics().next(), Some(GenericArgKind::Type(ty)));
|
||||
symbols.push((ExportedSymbol::AsyncDropGlueCtorShim(ty), SymbolExportInfo {
|
||||
level: SymbolExportLevel::Rust,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: false,
|
||||
}));
|
||||
symbols.push((
|
||||
ExportedSymbol::AsyncDropGlueCtorShim(ty),
|
||||
SymbolExportInfo {
|
||||
level: SymbolExportLevel::Rust,
|
||||
kind: SymbolExportKind::Text,
|
||||
used: false,
|
||||
},
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
// Any other symbols don't qualify for sharing
|
||||
|
@ -1604,10 +1604,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
if let Some(slot) = self.personality_slot {
|
||||
slot
|
||||
} else {
|
||||
let layout = cx.layout_of(Ty::new_tup(cx.tcx(), &[
|
||||
Ty::new_mut_ptr(cx.tcx(), cx.tcx().types.u8),
|
||||
cx.tcx().types.i32,
|
||||
]));
|
||||
let layout = cx.layout_of(Ty::new_tup(
|
||||
cx.tcx(),
|
||||
&[Ty::new_mut_ptr(cx.tcx(), cx.tcx().types.u8), cx.tcx().types.i32],
|
||||
));
|
||||
let slot = PlaceRef::alloca(bx, layout);
|
||||
self.personality_slot = Some(slot);
|
||||
slot
|
||||
|
@ -474,10 +474,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
LocalRef::Operand(..) => {
|
||||
if place_ref.is_indirect_first_projection() {
|
||||
base = 1;
|
||||
let cg_base = self.codegen_consume(bx, mir::PlaceRef {
|
||||
projection: &place_ref.projection[..0],
|
||||
..place_ref
|
||||
});
|
||||
let cg_base = self.codegen_consume(
|
||||
bx,
|
||||
mir::PlaceRef { projection: &place_ref.projection[..0], ..place_ref },
|
||||
);
|
||||
cg_base.deref(bx.cx())
|
||||
} else {
|
||||
bug!("using operand local {:?} as place", place_ref);
|
||||
|
@ -188,12 +188,14 @@ impl Qualif for NeedsNonConstDrop {
|
||||
ObligationCause::misc(cx.body.span, cx.def_id()),
|
||||
param_env,
|
||||
ty::Binder::dummy(ty::TraitRef::new(cx.tcx, destruct_def_id, [ty]))
|
||||
.to_host_effect_clause(cx.tcx, match cx.const_kind() {
|
||||
rustc_hir::ConstContext::ConstFn => ty::BoundConstness::Maybe,
|
||||
rustc_hir::ConstContext::Static(_) | rustc_hir::ConstContext::Const { .. } => {
|
||||
ty::BoundConstness::Const
|
||||
}
|
||||
}),
|
||||
.to_host_effect_clause(
|
||||
cx.tcx,
|
||||
match cx.const_kind() {
|
||||
rustc_hir::ConstContext::ConstFn => ty::BoundConstness::Maybe,
|
||||
rustc_hir::ConstContext::Static(_)
|
||||
| rustc_hir::ConstContext::Const { .. } => ty::BoundConstness::Const,
|
||||
},
|
||||
),
|
||||
));
|
||||
!ocx.select_all_or_error().is_empty()
|
||||
}
|
||||
|
@ -578,10 +578,13 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
|
||||
}
|
||||
ShiftOverflow { intrinsic, shift_amount } => {
|
||||
diag.arg("intrinsic", intrinsic);
|
||||
diag.arg("shift_amount", match shift_amount {
|
||||
Either::Left(v) => v.to_string(),
|
||||
Either::Right(v) => v.to_string(),
|
||||
});
|
||||
diag.arg(
|
||||
"shift_amount",
|
||||
match shift_amount {
|
||||
Either::Left(v) => v.to_string(),
|
||||
Either::Right(v) => v.to_string(),
|
||||
},
|
||||
);
|
||||
}
|
||||
BoundsCheckFailed { len, index } => {
|
||||
diag.arg("len", len);
|
||||
|
@ -381,10 +381,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
"caller ABI: {:#?}, args: {:#?}",
|
||||
caller_fn_abi,
|
||||
args.iter()
|
||||
.map(|arg| (arg.layout().ty, match arg {
|
||||
FnArg::Copy(op) => format!("copy({op:?})"),
|
||||
FnArg::InPlace(mplace) => format!("in-place({mplace:?})"),
|
||||
}))
|
||||
.map(|arg| (
|
||||
arg.layout().ty,
|
||||
match arg {
|
||||
FnArg::Copy(op) => format!("copy({op:?})"),
|
||||
FnArg::InPlace(mplace) => format!("in-place({mplace:?})"),
|
||||
}
|
||||
))
|
||||
.collect::<Vec<_>>()
|
||||
);
|
||||
trace!(
|
||||
@ -874,10 +877,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
);
|
||||
|
||||
// Check `unwinding`.
|
||||
assert_eq!(unwinding, match self.frame().loc {
|
||||
Left(loc) => self.body().basic_blocks[loc.block].is_cleanup,
|
||||
Right(_) => true,
|
||||
});
|
||||
assert_eq!(
|
||||
unwinding,
|
||||
match self.frame().loc {
|
||||
Left(loc) => self.body().basic_blocks[loc.block].is_cleanup,
|
||||
Right(_) => true,
|
||||
}
|
||||
);
|
||||
if unwinding && self.frame_idx() == 0 {
|
||||
throw_ub_custom!(fluent::const_eval_unwind_past_top);
|
||||
}
|
||||
|
@ -102,11 +102,11 @@ fn intern_as_new_static<'tcx>(
|
||||
alloc_id: AllocId,
|
||||
alloc: ConstAllocation<'tcx>,
|
||||
) {
|
||||
let feed = tcx.create_def(static_id, sym::nested, DefKind::Static {
|
||||
safety: hir::Safety::Safe,
|
||||
mutability: alloc.0.mutability,
|
||||
nested: true,
|
||||
});
|
||||
let feed = tcx.create_def(
|
||||
static_id,
|
||||
sym::nested,
|
||||
DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true },
|
||||
);
|
||||
tcx.set_nested_alloc_id_static(alloc_id, feed.def_id());
|
||||
|
||||
if tcx.is_thread_local_static(static_id.into()) {
|
||||
|
@ -812,10 +812,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
||||
if start == 1 && end == max_value {
|
||||
// Only null is the niche. So make sure the ptr is NOT null.
|
||||
if self.ecx.scalar_may_be_null(scalar)? {
|
||||
throw_validation_failure!(self.path, NullablePtrOutOfRange {
|
||||
range: valid_range,
|
||||
max_value
|
||||
})
|
||||
throw_validation_failure!(
|
||||
self.path,
|
||||
NullablePtrOutOfRange { range: valid_range, max_value }
|
||||
)
|
||||
} else {
|
||||
return interp_ok(());
|
||||
}
|
||||
@ -825,10 +825,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
||||
} else {
|
||||
// Conservatively, we reject, because the pointer *could* have a bad
|
||||
// value.
|
||||
throw_validation_failure!(self.path, PtrOutOfRange {
|
||||
range: valid_range,
|
||||
max_value
|
||||
})
|
||||
throw_validation_failure!(
|
||||
self.path,
|
||||
PtrOutOfRange { range: valid_range, max_value }
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -836,11 +836,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
||||
if valid_range.contains(bits) {
|
||||
interp_ok(())
|
||||
} else {
|
||||
throw_validation_failure!(self.path, OutOfRange {
|
||||
value: format!("{bits}"),
|
||||
range: valid_range,
|
||||
max_value
|
||||
})
|
||||
throw_validation_failure!(
|
||||
self.path,
|
||||
OutOfRange { value: format!("{bits}"), range: valid_range, max_value }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,17 +15,10 @@ fn diamond() {
|
||||
#[test]
|
||||
fn paper() {
|
||||
// example from the paper:
|
||||
let graph = TestGraph::new(6, &[
|
||||
(6, 5),
|
||||
(6, 4),
|
||||
(5, 1),
|
||||
(4, 2),
|
||||
(4, 3),
|
||||
(1, 2),
|
||||
(2, 3),
|
||||
(3, 2),
|
||||
(2, 1),
|
||||
]);
|
||||
let graph = TestGraph::new(
|
||||
6,
|
||||
&[(6, 5), (6, 4), (5, 1), (4, 2), (4, 3), (1, 2), (2, 3), (3, 2), (2, 1)],
|
||||
);
|
||||
|
||||
let d = dominators(&graph);
|
||||
assert_eq!(d.immediate_dominator(0), None); // <-- note that 0 is not in graph
|
||||
@ -40,19 +33,10 @@ fn paper() {
|
||||
#[test]
|
||||
fn paper_slt() {
|
||||
// example from the paper:
|
||||
let graph = TestGraph::new(1, &[
|
||||
(1, 2),
|
||||
(1, 3),
|
||||
(2, 3),
|
||||
(2, 7),
|
||||
(3, 4),
|
||||
(3, 6),
|
||||
(4, 5),
|
||||
(5, 4),
|
||||
(6, 7),
|
||||
(7, 8),
|
||||
(8, 5),
|
||||
]);
|
||||
let graph = TestGraph::new(
|
||||
1,
|
||||
&[(1, 2), (1, 3), (2, 3), (2, 7), (3, 4), (3, 6), (4, 5), (5, 4), (6, 7), (7, 8), (8, 5)],
|
||||
);
|
||||
|
||||
dominators(&graph);
|
||||
}
|
||||
@ -69,21 +53,24 @@ fn immediate_dominator() {
|
||||
|
||||
#[test]
|
||||
fn transitive_dominator() {
|
||||
let graph = TestGraph::new(0, &[
|
||||
// First tree branch.
|
||||
(0, 1),
|
||||
(1, 2),
|
||||
(2, 3),
|
||||
(3, 4),
|
||||
// Second tree branch.
|
||||
(1, 5),
|
||||
(5, 6),
|
||||
// Third tree branch.
|
||||
(0, 7),
|
||||
// These links make 0 the dominator for 2 and 3.
|
||||
(7, 2),
|
||||
(5, 3),
|
||||
]);
|
||||
let graph = TestGraph::new(
|
||||
0,
|
||||
&[
|
||||
// First tree branch.
|
||||
(0, 1),
|
||||
(1, 2),
|
||||
(2, 3),
|
||||
(3, 4),
|
||||
// Second tree branch.
|
||||
(1, 5),
|
||||
(5, 6),
|
||||
// Third tree branch.
|
||||
(0, 7),
|
||||
// These links make 0 the dominator for 2 and 3.
|
||||
(7, 2),
|
||||
(5, 3),
|
||||
],
|
||||
);
|
||||
|
||||
let d = dominators(&graph);
|
||||
assert_eq!(d.immediate_dominator(2), Some(0));
|
||||
|
@ -110,10 +110,13 @@ fn each_adjacent_from_a() {
|
||||
#[test]
|
||||
fn each_adjacent_from_b() {
|
||||
let graph = create_graph();
|
||||
test_adjacent_edges(&graph, NodeIndex(1), "B", &[("FB", "F"), ("AB", "A")], &[
|
||||
("BD", "D"),
|
||||
("BC", "C"),
|
||||
]);
|
||||
test_adjacent_edges(
|
||||
&graph,
|
||||
NodeIndex(1),
|
||||
"B",
|
||||
&[("FB", "F"), ("AB", "A")],
|
||||
&[("BD", "D"), ("BC", "C")],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -326,46 +326,49 @@ fn test_bug_max_leak_minimised() {
|
||||
|
||||
#[test]
|
||||
fn test_bug_max_leak() {
|
||||
let graph = TestGraph::new(8, &[
|
||||
(0, 0),
|
||||
(0, 18),
|
||||
(0, 19),
|
||||
(0, 1),
|
||||
(0, 2),
|
||||
(0, 7),
|
||||
(0, 8),
|
||||
(0, 23),
|
||||
(18, 0),
|
||||
(18, 12),
|
||||
(19, 0),
|
||||
(19, 25),
|
||||
(12, 18),
|
||||
(12, 3),
|
||||
(12, 5),
|
||||
(3, 12),
|
||||
(3, 21),
|
||||
(3, 22),
|
||||
(5, 13),
|
||||
(21, 3),
|
||||
(22, 3),
|
||||
(13, 5),
|
||||
(13, 4),
|
||||
(4, 13),
|
||||
(4, 0),
|
||||
(2, 11),
|
||||
(7, 6),
|
||||
(6, 20),
|
||||
(20, 6),
|
||||
(8, 17),
|
||||
(17, 9),
|
||||
(9, 16),
|
||||
(16, 26),
|
||||
(26, 15),
|
||||
(15, 10),
|
||||
(10, 14),
|
||||
(14, 27),
|
||||
(23, 24),
|
||||
]);
|
||||
let graph = TestGraph::new(
|
||||
8,
|
||||
&[
|
||||
(0, 0),
|
||||
(0, 18),
|
||||
(0, 19),
|
||||
(0, 1),
|
||||
(0, 2),
|
||||
(0, 7),
|
||||
(0, 8),
|
||||
(0, 23),
|
||||
(18, 0),
|
||||
(18, 12),
|
||||
(19, 0),
|
||||
(19, 25),
|
||||
(12, 18),
|
||||
(12, 3),
|
||||
(12, 5),
|
||||
(3, 12),
|
||||
(3, 21),
|
||||
(3, 22),
|
||||
(5, 13),
|
||||
(21, 3),
|
||||
(22, 3),
|
||||
(13, 5),
|
||||
(13, 4),
|
||||
(4, 13),
|
||||
(4, 0),
|
||||
(2, 11),
|
||||
(7, 6),
|
||||
(6, 20),
|
||||
(20, 6),
|
||||
(8, 17),
|
||||
(17, 9),
|
||||
(9, 16),
|
||||
(16, 26),
|
||||
(26, 15),
|
||||
(15, 10),
|
||||
(10, 14),
|
||||
(14, 27),
|
||||
(23, 24),
|
||||
],
|
||||
);
|
||||
let sccs: MaxReachedSccs = Sccs::new_with_annotation(&graph, |w| match w {
|
||||
22 => MaxReached(1),
|
||||
24 => MaxReached(2),
|
||||
|
@ -349,10 +349,10 @@ fn diamond() {
|
||||
));
|
||||
assert_eq!(d_count, 1);
|
||||
assert_eq!(ok.len(), 0);
|
||||
assert_eq!(err, vec![super::Error {
|
||||
error: "operation failed",
|
||||
backtrace: vec!["D'", "A'.1", "A'"]
|
||||
}]);
|
||||
assert_eq!(
|
||||
err,
|
||||
vec![super::Error { error: "operation failed", backtrace: vec!["D'", "A'.1", "A'"] }]
|
||||
);
|
||||
|
||||
let errors = forest.to_errors(());
|
||||
assert_eq!(errors.len(), 0);
|
||||
|
@ -58,11 +58,14 @@ fn concurrent_stress_check() {
|
||||
|
||||
#[test]
|
||||
fn slot_entries_table() {
|
||||
assert_eq!(ENTRIES_BY_BUCKET, [
|
||||
4096, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304,
|
||||
8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824,
|
||||
2147483648
|
||||
]);
|
||||
assert_eq!(
|
||||
ENTRIES_BY_BUCKET,
|
||||
[
|
||||
4096, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152,
|
||||
4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912,
|
||||
1073741824, 2147483648
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -69,96 +69,128 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
test_positions(" ", (0, 1), SpanTestData {
|
||||
byte_start: 0,
|
||||
byte_end: 1,
|
||||
line_start: 1,
|
||||
column_start: 1,
|
||||
line_end: 1,
|
||||
column_end: 2,
|
||||
})
|
||||
test_positions(
|
||||
" ",
|
||||
(0, 1),
|
||||
SpanTestData {
|
||||
byte_start: 0,
|
||||
byte_end: 1,
|
||||
line_start: 1,
|
||||
column_start: 1,
|
||||
line_end: 1,
|
||||
column_end: 2,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bom() {
|
||||
test_positions("\u{feff} ", (0, 1), SpanTestData {
|
||||
byte_start: 3,
|
||||
byte_end: 4,
|
||||
line_start: 1,
|
||||
column_start: 1,
|
||||
line_end: 1,
|
||||
column_end: 2,
|
||||
})
|
||||
test_positions(
|
||||
"\u{feff} ",
|
||||
(0, 1),
|
||||
SpanTestData {
|
||||
byte_start: 3,
|
||||
byte_end: 4,
|
||||
line_start: 1,
|
||||
column_start: 1,
|
||||
line_end: 1,
|
||||
column_end: 2,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lf_newlines() {
|
||||
test_positions("\nmod foo;\nmod bar;\n", (5, 12), SpanTestData {
|
||||
byte_start: 5,
|
||||
byte_end: 12,
|
||||
line_start: 2,
|
||||
column_start: 5,
|
||||
line_end: 3,
|
||||
column_end: 3,
|
||||
})
|
||||
test_positions(
|
||||
"\nmod foo;\nmod bar;\n",
|
||||
(5, 12),
|
||||
SpanTestData {
|
||||
byte_start: 5,
|
||||
byte_end: 12,
|
||||
line_start: 2,
|
||||
column_start: 5,
|
||||
line_end: 3,
|
||||
column_end: 3,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crlf_newlines() {
|
||||
test_positions("\r\nmod foo;\r\nmod bar;\r\n", (5, 12), SpanTestData {
|
||||
byte_start: 6,
|
||||
byte_end: 14,
|
||||
line_start: 2,
|
||||
column_start: 5,
|
||||
line_end: 3,
|
||||
column_end: 3,
|
||||
})
|
||||
test_positions(
|
||||
"\r\nmod foo;\r\nmod bar;\r\n",
|
||||
(5, 12),
|
||||
SpanTestData {
|
||||
byte_start: 6,
|
||||
byte_end: 14,
|
||||
line_start: 2,
|
||||
column_start: 5,
|
||||
line_end: 3,
|
||||
column_end: 3,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crlf_newlines_with_bom() {
|
||||
test_positions("\u{feff}\r\nmod foo;\r\nmod bar;\r\n", (5, 12), SpanTestData {
|
||||
byte_start: 9,
|
||||
byte_end: 17,
|
||||
line_start: 2,
|
||||
column_start: 5,
|
||||
line_end: 3,
|
||||
column_end: 3,
|
||||
})
|
||||
test_positions(
|
||||
"\u{feff}\r\nmod foo;\r\nmod bar;\r\n",
|
||||
(5, 12),
|
||||
SpanTestData {
|
||||
byte_start: 9,
|
||||
byte_end: 17,
|
||||
line_start: 2,
|
||||
column_start: 5,
|
||||
line_end: 3,
|
||||
column_end: 3,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn span_before_crlf() {
|
||||
test_positions("foo\r\nbar", (2, 3), SpanTestData {
|
||||
byte_start: 2,
|
||||
byte_end: 3,
|
||||
line_start: 1,
|
||||
column_start: 3,
|
||||
line_end: 1,
|
||||
column_end: 4,
|
||||
})
|
||||
test_positions(
|
||||
"foo\r\nbar",
|
||||
(2, 3),
|
||||
SpanTestData {
|
||||
byte_start: 2,
|
||||
byte_end: 3,
|
||||
line_start: 1,
|
||||
column_start: 3,
|
||||
line_end: 1,
|
||||
column_end: 4,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn span_on_crlf() {
|
||||
test_positions("foo\r\nbar", (3, 4), SpanTestData {
|
||||
byte_start: 3,
|
||||
byte_end: 5,
|
||||
line_start: 1,
|
||||
column_start: 4,
|
||||
line_end: 2,
|
||||
column_end: 1,
|
||||
})
|
||||
test_positions(
|
||||
"foo\r\nbar",
|
||||
(3, 4),
|
||||
SpanTestData {
|
||||
byte_start: 3,
|
||||
byte_end: 5,
|
||||
line_start: 1,
|
||||
column_start: 4,
|
||||
line_end: 2,
|
||||
column_end: 1,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn span_after_crlf() {
|
||||
test_positions("foo\r\nbar", (4, 5), SpanTestData {
|
||||
byte_start: 5,
|
||||
byte_end: 6,
|
||||
line_start: 2,
|
||||
column_start: 1,
|
||||
line_end: 2,
|
||||
column_end: 2,
|
||||
})
|
||||
test_positions(
|
||||
"foo\r\nbar",
|
||||
(4, 5),
|
||||
SpanTestData {
|
||||
byte_start: 5,
|
||||
byte_end: 6,
|
||||
line_start: 2,
|
||||
column_start: 1,
|
||||
line_end: 2,
|
||||
column_end: 2,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -233,11 +233,14 @@ impl<'a> ExtCtxt<'a> {
|
||||
}
|
||||
|
||||
pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
|
||||
self.block(expr.span, thin_vec![ast::Stmt {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: expr.span,
|
||||
kind: ast::StmtKind::Expr(expr),
|
||||
}])
|
||||
self.block(
|
||||
expr.span,
|
||||
thin_vec![ast::Stmt {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: expr.span,
|
||||
kind: ast::StmtKind::Expr(expr),
|
||||
}],
|
||||
)
|
||||
}
|
||||
pub fn block(&self, span: Span, stmts: ThinVec<ast::Stmt>) -> P<ast::Block> {
|
||||
P(ast::Block {
|
||||
|
@ -405,26 +405,35 @@ pub fn compile_declarative_macro(
|
||||
// ...quasiquoting this would be nice.
|
||||
// These spans won't matter, anyways
|
||||
let argument_gram = vec![
|
||||
mbe::TokenTree::Sequence(DelimSpan::dummy(), mbe::SequenceRepetition {
|
||||
tts: vec![
|
||||
mbe::TokenTree::MetaVarDecl(span, lhs_nm, tt_spec),
|
||||
mbe::TokenTree::token(token::FatArrow, span),
|
||||
mbe::TokenTree::MetaVarDecl(span, rhs_nm, tt_spec),
|
||||
],
|
||||
separator: Some(Token::new(if macro_rules { token::Semi } else { token::Comma }, span)),
|
||||
kleene: mbe::KleeneToken::new(mbe::KleeneOp::OneOrMore, span),
|
||||
num_captures: 2,
|
||||
}),
|
||||
mbe::TokenTree::Sequence(
|
||||
DelimSpan::dummy(),
|
||||
mbe::SequenceRepetition {
|
||||
tts: vec![
|
||||
mbe::TokenTree::MetaVarDecl(span, lhs_nm, tt_spec),
|
||||
mbe::TokenTree::token(token::FatArrow, span),
|
||||
mbe::TokenTree::MetaVarDecl(span, rhs_nm, tt_spec),
|
||||
],
|
||||
separator: Some(Token::new(
|
||||
if macro_rules { token::Semi } else { token::Comma },
|
||||
span,
|
||||
)),
|
||||
kleene: mbe::KleeneToken::new(mbe::KleeneOp::OneOrMore, span),
|
||||
num_captures: 2,
|
||||
},
|
||||
),
|
||||
// to phase into semicolon-termination instead of semicolon-separation
|
||||
mbe::TokenTree::Sequence(DelimSpan::dummy(), mbe::SequenceRepetition {
|
||||
tts: vec![mbe::TokenTree::token(
|
||||
if macro_rules { token::Semi } else { token::Comma },
|
||||
span,
|
||||
)],
|
||||
separator: None,
|
||||
kleene: mbe::KleeneToken::new(mbe::KleeneOp::ZeroOrMore, span),
|
||||
num_captures: 0,
|
||||
}),
|
||||
mbe::TokenTree::Sequence(
|
||||
DelimSpan::dummy(),
|
||||
mbe::SequenceRepetition {
|
||||
tts: vec![mbe::TokenTree::token(
|
||||
if macro_rules { token::Semi } else { token::Comma },
|
||||
span,
|
||||
)],
|
||||
separator: None,
|
||||
kleene: mbe::KleeneToken::new(mbe::KleeneOp::ZeroOrMore, span),
|
||||
num_captures: 0,
|
||||
},
|
||||
),
|
||||
];
|
||||
// Convert it into `MatcherLoc` form.
|
||||
let argument_gram = mbe::macro_parser::compute_locs(&argument_gram);
|
||||
|
@ -179,10 +179,10 @@ fn parse_tree<'a>(
|
||||
Some(&tokenstream::TokenTree::Delimited(delim_span, _, delim, ref tts)) => {
|
||||
if parsing_patterns {
|
||||
if delim != Delimiter::Parenthesis {
|
||||
span_dollar_dollar_or_metavar_in_the_lhs_err(sess, &Token {
|
||||
kind: token::OpenDelim(delim),
|
||||
span: delim_span.entire(),
|
||||
});
|
||||
span_dollar_dollar_or_metavar_in_the_lhs_err(
|
||||
sess,
|
||||
&Token { kind: token::OpenDelim(delim), span: delim_span.entire() },
|
||||
);
|
||||
}
|
||||
} else {
|
||||
match delim {
|
||||
@ -235,12 +235,10 @@ fn parse_tree<'a>(
|
||||
// Count the number of captured "names" (i.e., named metavars)
|
||||
let num_captures =
|
||||
if parsing_patterns { count_metavar_decls(&sequence) } else { 0 };
|
||||
TokenTree::Sequence(delim_span, SequenceRepetition {
|
||||
tts: sequence,
|
||||
separator,
|
||||
kleene,
|
||||
num_captures,
|
||||
})
|
||||
TokenTree::Sequence(
|
||||
delim_span,
|
||||
SequenceRepetition { tts: sequence, separator, kleene, num_captures },
|
||||
)
|
||||
}
|
||||
|
||||
// `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate`
|
||||
@ -261,10 +259,10 @@ fn parse_tree<'a>(
|
||||
_,
|
||||
)) => {
|
||||
if parsing_patterns {
|
||||
span_dollar_dollar_or_metavar_in_the_lhs_err(sess, &Token {
|
||||
kind: token::Dollar,
|
||||
span: dollar_span2,
|
||||
});
|
||||
span_dollar_dollar_or_metavar_in_the_lhs_err(
|
||||
sess,
|
||||
&Token { kind: token::Dollar, span: dollar_span2 },
|
||||
);
|
||||
} else {
|
||||
maybe_emit_macro_metavar_expr_feature(features, sess, dollar_span2);
|
||||
}
|
||||
@ -289,12 +287,14 @@ fn parse_tree<'a>(
|
||||
|
||||
// `tree` is the beginning of a delimited set of tokens (e.g., `(` or `{`). We need to
|
||||
// descend into the delimited set and further parse it.
|
||||
&tokenstream::TokenTree::Delimited(span, spacing, delim, ref tts) => {
|
||||
TokenTree::Delimited(span, spacing, Delimited {
|
||||
&tokenstream::TokenTree::Delimited(span, spacing, delim, ref tts) => TokenTree::Delimited(
|
||||
span,
|
||||
spacing,
|
||||
Delimited {
|
||||
delim,
|
||||
tts: parse(tts, parsing_patterns, sess, node_id, features, edition),
|
||||
})
|
||||
}
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,12 +360,16 @@ fn left_aligned_text() {
|
||||
|
||||
let mut writer = Vec::new();
|
||||
|
||||
let g = LabelledGraphWithEscStrs::new("syntax_tree", labels, vec![
|
||||
edge(0, 1, "then", Style::None),
|
||||
edge(0, 2, "else", Style::None),
|
||||
edge(1, 3, ";", Style::None),
|
||||
edge(2, 3, ";", Style::None),
|
||||
]);
|
||||
let g = LabelledGraphWithEscStrs::new(
|
||||
"syntax_tree",
|
||||
labels,
|
||||
vec![
|
||||
edge(0, 1, "then", Style::None),
|
||||
edge(0, 2, "else", Style::None),
|
||||
edge(1, 3, ";", Style::None),
|
||||
edge(2, 3, ";", Style::None),
|
||||
],
|
||||
);
|
||||
|
||||
render(&g, &mut writer).unwrap();
|
||||
let mut r = String::new();
|
||||
|
@ -3101,10 +3101,10 @@ impl<'hir> Ty<'hir> {
|
||||
fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
|
||||
if matches!(
|
||||
&t.kind,
|
||||
TyKind::Path(QPath::Resolved(_, Path {
|
||||
res: crate::def::Res::SelfTyAlias { .. },
|
||||
..
|
||||
},))
|
||||
TyKind::Path(QPath::Resolved(
|
||||
_,
|
||||
Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
|
||||
))
|
||||
) {
|
||||
self.0.push(t.span);
|
||||
return;
|
||||
@ -3446,11 +3446,10 @@ impl<'hir> InlineAsmOperand<'hir> {
|
||||
}
|
||||
|
||||
pub fn is_clobber(&self) -> bool {
|
||||
matches!(self, InlineAsmOperand::Out {
|
||||
reg: InlineAsmRegOrRegClass::Reg(_),
|
||||
late: _,
|
||||
expr: None
|
||||
})
|
||||
matches!(
|
||||
self,
|
||||
InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,12 +182,15 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||
// obligations.
|
||||
let impl_m_def_id = impl_m.def_id.expect_local();
|
||||
let impl_m_span = tcx.def_span(impl_m_def_id);
|
||||
let cause =
|
||||
ObligationCause::new(impl_m_span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
|
||||
let cause = ObligationCause::new(
|
||||
impl_m_span,
|
||||
impl_m_def_id,
|
||||
ObligationCauseCode::CompareImplItem {
|
||||
impl_item_def_id: impl_m_def_id,
|
||||
trait_item_def_id: trait_m.def_id,
|
||||
kind: impl_m.kind,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// Create mapping from trait method to impl method.
|
||||
let impl_def_id = impl_m.container_id(tcx);
|
||||
@ -248,12 +251,15 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
|
||||
let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
|
||||
|
||||
let cause =
|
||||
ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
impl_m_def_id,
|
||||
ObligationCauseCode::CompareImplItem {
|
||||
impl_item_def_id: impl_m_def_id,
|
||||
trait_item_def_id: trait_m.def_id,
|
||||
kind: impl_m.kind,
|
||||
});
|
||||
},
|
||||
);
|
||||
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
|
||||
}
|
||||
|
||||
@ -270,12 +276,15 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
|
||||
let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition);
|
||||
|
||||
let cause =
|
||||
ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
impl_m_def_id,
|
||||
ObligationCauseCode::CompareImplItem {
|
||||
impl_item_def_id: impl_m_def_id,
|
||||
trait_item_def_id: trait_m.def_id,
|
||||
kind: impl_m.kind,
|
||||
});
|
||||
},
|
||||
);
|
||||
ocx.register_obligation(traits::Obligation::new(
|
||||
tcx,
|
||||
cause,
|
||||
@ -493,12 +502,15 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||
|
||||
let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
|
||||
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
|
||||
let cause =
|
||||
ObligationCause::new(return_span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
|
||||
let cause = ObligationCause::new(
|
||||
return_span,
|
||||
impl_m_def_id,
|
||||
ObligationCauseCode::CompareImplItem {
|
||||
impl_item_def_id: impl_m_def_id,
|
||||
trait_item_def_id: trait_m.def_id,
|
||||
kind: impl_m.kind,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// Create mapping from trait to impl (i.e. impl trait header + impl method identity args).
|
||||
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
|
||||
@ -534,12 +546,15 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
|
||||
let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
|
||||
|
||||
let cause =
|
||||
ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
impl_m_def_id,
|
||||
ObligationCauseCode::CompareImplItem {
|
||||
impl_item_def_id: impl_m_def_id,
|
||||
trait_item_def_id: trait_m.def_id,
|
||||
kind: impl_m.kind,
|
||||
});
|
||||
},
|
||||
);
|
||||
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
|
||||
}
|
||||
|
||||
@ -606,13 +621,16 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||
idx += 1;
|
||||
(
|
||||
ty,
|
||||
Ty::new_placeholder(tcx, ty::Placeholder {
|
||||
universe,
|
||||
bound: ty::BoundTy {
|
||||
var: ty::BoundVar::from_usize(idx),
|
||||
kind: ty::BoundTyKind::Anon,
|
||||
Ty::new_placeholder(
|
||||
tcx,
|
||||
ty::Placeholder {
|
||||
universe,
|
||||
bound: ty::BoundTy {
|
||||
var: ty::BoundVar::from_usize(idx),
|
||||
kind: ty::BoundTyKind::Anon,
|
||||
},
|
||||
},
|
||||
}),
|
||||
),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
@ -969,10 +987,13 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
||||
return Err(guar);
|
||||
};
|
||||
|
||||
Ok(ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
|
||||
name: e.name,
|
||||
index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
|
||||
}))
|
||||
Ok(ty::Region::new_early_param(
|
||||
self.tcx,
|
||||
ty::EarlyParamRegion {
|
||||
name: e.name,
|
||||
index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1967,12 +1988,15 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||
let cause = ObligationCause::misc(span, impl_ty_def_id);
|
||||
let predicate = ocx.normalize(&cause, param_env, predicate);
|
||||
|
||||
let cause =
|
||||
ObligationCause::new(span, impl_ty_def_id, ObligationCauseCode::CompareImplItem {
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
impl_ty_def_id,
|
||||
ObligationCauseCode::CompareImplItem {
|
||||
impl_item_def_id: impl_ty.def_id.expect_local(),
|
||||
trait_item_def_id: trait_ty.def_id,
|
||||
kind: impl_ty.kind,
|
||||
});
|
||||
},
|
||||
);
|
||||
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
|
||||
}
|
||||
|
||||
@ -1984,12 +2008,15 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||
let normalize_cause = traits::ObligationCause::misc(span, impl_ty_def_id);
|
||||
let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition);
|
||||
|
||||
let cause =
|
||||
ObligationCause::new(span, impl_ty_def_id, ObligationCauseCode::CompareImplItem {
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
impl_ty_def_id,
|
||||
ObligationCauseCode::CompareImplItem {
|
||||
impl_item_def_id: impl_ty_def_id,
|
||||
trait_item_def_id: trait_ty.def_id,
|
||||
kind: impl_ty.kind,
|
||||
});
|
||||
},
|
||||
);
|
||||
ocx.register_obligation(traits::Obligation::new(
|
||||
tcx,
|
||||
cause,
|
||||
@ -2244,20 +2271,25 @@ fn param_env_with_gat_bounds<'tcx>(
|
||||
let kind = ty::BoundTyKind::Param(param.def_id, param.name);
|
||||
let bound_var = ty::BoundVariableKind::Ty(kind);
|
||||
bound_vars.push(bound_var);
|
||||
Ty::new_bound(tcx, ty::INNERMOST, ty::BoundTy {
|
||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||
kind,
|
||||
})
|
||||
Ty::new_bound(
|
||||
tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundTy { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
|
||||
)
|
||||
.into()
|
||||
}
|
||||
GenericParamDefKind::Lifetime => {
|
||||
let kind = ty::BoundRegionKind::Named(param.def_id, param.name);
|
||||
let bound_var = ty::BoundVariableKind::Region(kind);
|
||||
bound_vars.push(bound_var);
|
||||
ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
|
||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||
kind,
|
||||
})
|
||||
ty::Region::new_bound(
|
||||
tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion {
|
||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||
kind,
|
||||
},
|
||||
)
|
||||
.into()
|
||||
}
|
||||
GenericParamDefKind::Const { .. } => {
|
||||
|
@ -185,14 +185,19 @@ pub fn check_intrinsic_type(
|
||||
]);
|
||||
let mk_va_list_ty = |mutbl| {
|
||||
tcx.lang_items().va_list().map(|did| {
|
||||
let region = ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
|
||||
var: ty::BoundVar::ZERO,
|
||||
kind: ty::BoundRegionKind::Anon,
|
||||
});
|
||||
let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(2),
|
||||
kind: ty::BoundRegionKind::ClosureEnv,
|
||||
});
|
||||
let region = ty::Region::new_bound(
|
||||
tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon },
|
||||
);
|
||||
let env_region = ty::Region::new_bound(
|
||||
tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(2),
|
||||
kind: ty::BoundRegionKind::ClosureEnv,
|
||||
},
|
||||
);
|
||||
let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]);
|
||||
(Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty)
|
||||
})
|
||||
|
@ -675,10 +675,10 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
// Same for the region. In our example, 'a corresponds
|
||||
// to the 'me parameter.
|
||||
let region_param = gat_generics.param_at(*region_a_idx, tcx);
|
||||
let region_param = ty::Region::new_early_param(tcx, ty::EarlyParamRegion {
|
||||
index: region_param.index,
|
||||
name: region_param.name,
|
||||
});
|
||||
let region_param = ty::Region::new_early_param(
|
||||
tcx,
|
||||
ty::EarlyParamRegion { index: region_param.index, name: region_param.name },
|
||||
);
|
||||
// The predicate we expect to see. (In our example,
|
||||
// `Self: 'me`.)
|
||||
bounds.insert(
|
||||
@ -704,16 +704,16 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
debug!("required clause: {region_a} must outlive {region_b}");
|
||||
// Translate into the generic parameters of the GAT.
|
||||
let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
|
||||
let region_a_param = ty::Region::new_early_param(tcx, ty::EarlyParamRegion {
|
||||
index: region_a_param.index,
|
||||
name: region_a_param.name,
|
||||
});
|
||||
let region_a_param = ty::Region::new_early_param(
|
||||
tcx,
|
||||
ty::EarlyParamRegion { index: region_a_param.index, name: region_a_param.name },
|
||||
);
|
||||
// Same for the region.
|
||||
let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
|
||||
let region_b_param = ty::Region::new_early_param(tcx, ty::EarlyParamRegion {
|
||||
index: region_b_param.index,
|
||||
name: region_b_param.name,
|
||||
});
|
||||
let region_b_param = ty::Region::new_early_param(
|
||||
tcx,
|
||||
ty::EarlyParamRegion { index: region_b_param.index, name: region_b_param.name },
|
||||
);
|
||||
// The predicate we expect to see.
|
||||
bounds.insert(
|
||||
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
|
||||
@ -1647,10 +1647,15 @@ fn check_fn_or_method<'tcx>(
|
||||
}
|
||||
|
||||
// If the function has a body, additionally require that the return type is sized.
|
||||
check_sized_if_body(wfcx, def_id, sig.output(), match hir_decl.output {
|
||||
hir::FnRetTy::Return(ty) => Some(ty.span),
|
||||
hir::FnRetTy::DefaultReturn(_) => None,
|
||||
});
|
||||
check_sized_if_body(
|
||||
wfcx,
|
||||
def_id,
|
||||
sig.output(),
|
||||
match hir_decl.output {
|
||||
hir::FnRetTy::Return(ty) => Some(ty.span),
|
||||
hir::FnRetTy::DefaultReturn(_) => None,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn check_sized_if_body<'tcx>(
|
||||
|
@ -333,10 +333,11 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||
tcx,
|
||||
cause.clone(),
|
||||
param_env,
|
||||
ty::TraitRef::new(tcx, dispatch_from_dyn_trait, [
|
||||
field.ty(tcx, args_a),
|
||||
field.ty(tcx, args_b),
|
||||
]),
|
||||
ty::TraitRef::new(
|
||||
tcx,
|
||||
dispatch_from_dyn_trait,
|
||||
[field.ty(tcx, args_a), field.ty(tcx, args_b)],
|
||||
),
|
||||
));
|
||||
}
|
||||
let errors = ocx.select_all_or_error();
|
||||
|
@ -251,10 +251,13 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
||||
for ident in &idents_to_add {
|
||||
connected_region_ids.insert(*ident, id_to_set);
|
||||
}
|
||||
connected_regions.insert(id_to_set, ConnectedRegion {
|
||||
idents: idents_to_add,
|
||||
impl_blocks: std::iter::once(i).collect(),
|
||||
});
|
||||
connected_regions.insert(
|
||||
id_to_set,
|
||||
ConnectedRegion {
|
||||
idents: idents_to_add,
|
||||
impl_blocks: std::iter::once(i).collect(),
|
||||
},
|
||||
);
|
||||
}
|
||||
// Take the only id inside the list
|
||||
&[id_to_set] => {
|
||||
|
@ -242,10 +242,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
|
||||
// Allocate a new var idx, and insert a new bound ty.
|
||||
let var = ty::BoundVar::from_usize(self.still_bound_vars.len());
|
||||
self.still_bound_vars.push(ty::BoundVariableKind::Ty(old_bound.kind));
|
||||
let mapped = Ty::new_bound(self.tcx, ty::INNERMOST, ty::BoundTy {
|
||||
var,
|
||||
kind: old_bound.kind,
|
||||
});
|
||||
let mapped = Ty::new_bound(
|
||||
self.tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundTy { var, kind: old_bound.kind },
|
||||
);
|
||||
self.mapping.insert(old_bound.var, mapped.into());
|
||||
mapped
|
||||
};
|
||||
@ -265,10 +266,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
|
||||
} else {
|
||||
let var = ty::BoundVar::from_usize(self.still_bound_vars.len());
|
||||
self.still_bound_vars.push(ty::BoundVariableKind::Region(old_bound.kind));
|
||||
let mapped = ty::Region::new_bound(self.tcx, ty::INNERMOST, ty::BoundRegion {
|
||||
var,
|
||||
kind: old_bound.kind,
|
||||
});
|
||||
let mapped = ty::Region::new_bound(
|
||||
self.tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var, kind: old_bound.kind },
|
||||
);
|
||||
self.mapping.insert(old_bound.var, mapped.into());
|
||||
mapped
|
||||
};
|
||||
|
@ -350,10 +350,10 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
|
||||
for param in opaque_own_params {
|
||||
let orig_lifetime = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
|
||||
if let ty::ReEarlyParam(..) = *orig_lifetime {
|
||||
let dup_lifetime = ty::Region::new_early_param(tcx, ty::EarlyParamRegion {
|
||||
index: param.index,
|
||||
name: param.name,
|
||||
});
|
||||
let dup_lifetime = ty::Region::new_early_param(
|
||||
tcx,
|
||||
ty::EarlyParamRegion { index: param.index, name: param.name },
|
||||
);
|
||||
let span = tcx.def_span(param.def_id);
|
||||
predicates.push((
|
||||
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_lifetime, dup_lifetime))
|
||||
|
@ -1143,20 +1143,23 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||
.params
|
||||
.iter()
|
||||
.map(|param| {
|
||||
(param.def_id, match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
if self.tcx.is_late_bound(param.hir_id) {
|
||||
let late_bound_idx = named_late_bound_vars;
|
||||
named_late_bound_vars += 1;
|
||||
ResolvedArg::late(late_bound_idx, param)
|
||||
} else {
|
||||
(
|
||||
param.def_id,
|
||||
match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
if self.tcx.is_late_bound(param.hir_id) {
|
||||
let late_bound_idx = named_late_bound_vars;
|
||||
named_late_bound_vars += 1;
|
||||
ResolvedArg::late(late_bound_idx, param)
|
||||
} else {
|
||||
ResolvedArg::early(param)
|
||||
}
|
||||
}
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
|
||||
ResolvedArg::early(param)
|
||||
}
|
||||
}
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
|
||||
ResolvedArg::early(param)
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
@ -41,10 +41,10 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamIndexRemapper<'tcx> {
|
||||
if let ty::ReEarlyParam(param) = r.kind()
|
||||
&& let Some(index) = self.remap_table.get(¶m.index).copied()
|
||||
{
|
||||
return ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
|
||||
index,
|
||||
name: param.name,
|
||||
});
|
||||
return ty::Region::new_early_param(
|
||||
self.tcx,
|
||||
ty::EarlyParamRegion { index, name: param.name },
|
||||
);
|
||||
}
|
||||
r
|
||||
}
|
||||
|
@ -640,13 +640,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
let mut num_bound_vars = candidate.bound_vars().len();
|
||||
let args = candidate.skip_binder().args.extend_to(tcx, item_def_id, |param, _| {
|
||||
let arg = match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime => {
|
||||
ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
|
||||
ty::GenericParamDefKind::Lifetime => ty::Region::new_bound(
|
||||
tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion {
|
||||
var: ty::BoundVar::from_usize(num_bound_vars),
|
||||
kind: ty::BoundRegionKind::Named(param.def_id, param.name),
|
||||
})
|
||||
.into()
|
||||
}
|
||||
},
|
||||
)
|
||||
.into(),
|
||||
ty::GenericParamDefKind::Type { .. } => {
|
||||
let guar = *emitted_bad_param_err.get_or_insert_with(|| {
|
||||
self.dcx().emit_err(crate::errors::ReturnTypeNotationIllegalParam::Type {
|
||||
|
@ -107,12 +107,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
let mut needed_associated_types = FxIndexSet::default();
|
||||
if let Some((principal_trait, spans)) = &principal_trait {
|
||||
let pred: ty::Predicate<'tcx> = (*principal_trait).upcast(tcx);
|
||||
for ClauseWithSupertraitSpan { pred, supertrait_span } in
|
||||
traits::elaborate(tcx, [ClauseWithSupertraitSpan::new(
|
||||
pred,
|
||||
*spans.last().unwrap(),
|
||||
)])
|
||||
.filter_only_self()
|
||||
for ClauseWithSupertraitSpan { pred, supertrait_span } in traits::elaborate(
|
||||
tcx,
|
||||
[ClauseWithSupertraitSpan::new(pred, *spans.last().unwrap())],
|
||||
)
|
||||
.filter_only_self()
|
||||
{
|
||||
debug!("observing object predicate `{pred:?}`");
|
||||
|
||||
|
@ -2219,10 +2219,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
|
||||
match self.try_lower_anon_const_lit(ty, expr) {
|
||||
Some(v) => v,
|
||||
None => ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst {
|
||||
def: anon.def_id.to_def_id(),
|
||||
args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
|
||||
}),
|
||||
None => ty::Const::new_unevaluated(
|
||||
tcx,
|
||||
ty::UnevaluatedConst {
|
||||
def: anon.def_id.to_def_id(),
|
||||
args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2226,10 +2226,13 @@ impl<'a> State<'a> {
|
||||
let generic_params = generic_params
|
||||
.iter()
|
||||
.filter(|p| {
|
||||
matches!(p, GenericParam {
|
||||
kind: GenericParamKind::Lifetime { kind: LifetimeParamKind::Explicit },
|
||||
..
|
||||
})
|
||||
matches!(
|
||||
p,
|
||||
GenericParam {
|
||||
kind: GenericParamKind::Lifetime { kind: LifetimeParamKind::Explicit },
|
||||
..
|
||||
}
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -153,13 +153,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
closure_sig,
|
||||
);
|
||||
let adjustments = self.adjust_steps(autoderef);
|
||||
self.record_deferred_call_resolution(def_id, DeferredCallResolution {
|
||||
call_expr,
|
||||
callee_expr,
|
||||
closure_ty: adjusted_ty,
|
||||
adjustments,
|
||||
fn_sig: closure_sig,
|
||||
});
|
||||
self.record_deferred_call_resolution(
|
||||
def_id,
|
||||
DeferredCallResolution {
|
||||
call_expr,
|
||||
callee_expr,
|
||||
closure_ty: adjusted_ty,
|
||||
adjustments,
|
||||
fn_sig: closure_sig,
|
||||
},
|
||||
);
|
||||
return Some(CallStep::DeferredClosure(def_id, closure_sig));
|
||||
}
|
||||
|
||||
@ -196,13 +199,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
coroutine_closure_sig.abi,
|
||||
);
|
||||
let adjustments = self.adjust_steps(autoderef);
|
||||
self.record_deferred_call_resolution(def_id, DeferredCallResolution {
|
||||
call_expr,
|
||||
callee_expr,
|
||||
closure_ty: adjusted_ty,
|
||||
adjustments,
|
||||
fn_sig: call_sig,
|
||||
});
|
||||
self.record_deferred_call_resolution(
|
||||
def_id,
|
||||
DeferredCallResolution {
|
||||
call_expr,
|
||||
callee_expr,
|
||||
closure_ty: adjusted_ty,
|
||||
adjustments,
|
||||
fn_sig: call_sig,
|
||||
},
|
||||
);
|
||||
return Some(CallStep::DeferredClosure(def_id, call_sig));
|
||||
}
|
||||
|
||||
|
@ -666,11 +666,12 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||
};
|
||||
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
|
||||
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
|
||||
fcx.tcx.emit_node_span_lint(lint, self.expr.hir_id, self.span, errors::TrivialCast {
|
||||
numeric,
|
||||
expr_ty,
|
||||
cast_ty,
|
||||
});
|
||||
fcx.tcx.emit_node_span_lint(
|
||||
lint,
|
||||
self.expr.hir_id,
|
||||
self.span,
|
||||
errors::TrivialCast { numeric, expr_ty, cast_ty },
|
||||
);
|
||||
}
|
||||
|
||||
#[instrument(skip(fcx), level = "debug")]
|
||||
|
@ -186,18 +186,21 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
|
||||
let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, Some(span));
|
||||
|
||||
// build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
|
||||
let panic_info_ty = tcx.type_of(panic_info_did).instantiate(tcx, &[ty::GenericArg::from(
|
||||
ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(1),
|
||||
kind: ty::BoundRegionKind::Anon,
|
||||
}),
|
||||
)]);
|
||||
let panic_info_ty = tcx.type_of(panic_info_did).instantiate(
|
||||
tcx,
|
||||
&[ty::GenericArg::from(ty::Region::new_bound(
|
||||
tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BoundRegionKind::Anon },
|
||||
))],
|
||||
);
|
||||
let panic_info_ref_ty = Ty::new_imm_ref(
|
||||
tcx,
|
||||
ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
|
||||
var: ty::BoundVar::ZERO,
|
||||
kind: ty::BoundRegionKind::Anon,
|
||||
}),
|
||||
ty::Region::new_bound(
|
||||
tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon },
|
||||
),
|
||||
panic_info_ty,
|
||||
);
|
||||
|
||||
|
@ -103,12 +103,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
None => self.next_ty_var(expr_span),
|
||||
};
|
||||
|
||||
let closure_args = ty::ClosureArgs::new(tcx, ty::ClosureArgsParts {
|
||||
parent_args,
|
||||
closure_kind_ty,
|
||||
closure_sig_as_fn_ptr_ty: Ty::new_fn_ptr(tcx, sig),
|
||||
tupled_upvars_ty,
|
||||
});
|
||||
let closure_args = ty::ClosureArgs::new(
|
||||
tcx,
|
||||
ty::ClosureArgsParts {
|
||||
parent_args,
|
||||
closure_kind_ty,
|
||||
closure_sig_as_fn_ptr_ty: Ty::new_fn_ptr(tcx, sig),
|
||||
tupled_upvars_ty,
|
||||
},
|
||||
);
|
||||
|
||||
(Ty::new_closure(tcx, expr_def_id.to_def_id(), closure_args.args), None)
|
||||
}
|
||||
@ -177,15 +180,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
_ => tcx.types.unit,
|
||||
};
|
||||
|
||||
let coroutine_args = ty::CoroutineArgs::new(tcx, ty::CoroutineArgsParts {
|
||||
parent_args,
|
||||
kind_ty,
|
||||
resume_ty,
|
||||
yield_ty,
|
||||
return_ty: liberated_sig.output(),
|
||||
witness: interior,
|
||||
tupled_upvars_ty,
|
||||
});
|
||||
let coroutine_args = ty::CoroutineArgs::new(
|
||||
tcx,
|
||||
ty::CoroutineArgsParts {
|
||||
parent_args,
|
||||
kind_ty,
|
||||
resume_ty,
|
||||
yield_ty,
|
||||
return_ty: liberated_sig.output(),
|
||||
witness: interior,
|
||||
tupled_upvars_ty,
|
||||
},
|
||||
);
|
||||
|
||||
(
|
||||
Ty::new_coroutine(tcx, expr_def_id.to_def_id(), coroutine_args.args),
|
||||
@ -216,8 +222,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let coroutine_captures_by_ref_ty = self.next_ty_var(expr_span);
|
||||
let closure_args =
|
||||
ty::CoroutineClosureArgs::new(tcx, ty::CoroutineClosureArgsParts {
|
||||
let closure_args = ty::CoroutineClosureArgs::new(
|
||||
tcx,
|
||||
ty::CoroutineClosureArgsParts {
|
||||
parent_args,
|
||||
closure_kind_ty,
|
||||
signature_parts_ty: Ty::new_fn_ptr(
|
||||
@ -238,7 +245,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
tupled_upvars_ty,
|
||||
coroutine_captures_by_ref_ty,
|
||||
coroutine_witness_ty: interior,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
let coroutine_kind_ty = match expected_kind {
|
||||
Some(kind) => Ty::from_coroutine_closure_kind(tcx, kind),
|
||||
|
@ -555,18 +555,24 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
// the reborrow in coerce_borrowed_ptr will pick it up.
|
||||
let mutbl = AutoBorrowMutability::new(mutbl_b, AllowTwoPhase::No);
|
||||
|
||||
Some((Adjustment { kind: Adjust::Deref(None), target: ty_a }, Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
|
||||
target: Ty::new_ref(self.tcx, r_borrow, ty_a, mutbl_b),
|
||||
}))
|
||||
Some((
|
||||
Adjustment { kind: Adjust::Deref(None), target: ty_a },
|
||||
Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
|
||||
target: Ty::new_ref(self.tcx, r_borrow, ty_a, mutbl_b),
|
||||
},
|
||||
))
|
||||
}
|
||||
(&ty::Ref(_, ty_a, mt_a), &ty::RawPtr(_, mt_b)) => {
|
||||
coerce_mutbls(mt_a, mt_b)?;
|
||||
|
||||
Some((Adjustment { kind: Adjust::Deref(None), target: ty_a }, Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b)),
|
||||
target: Ty::new_ptr(self.tcx, ty_a, mt_b),
|
||||
}))
|
||||
Some((
|
||||
Adjustment { kind: Adjust::Deref(None), target: ty_a },
|
||||
Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b)),
|
||||
target: Ty::new_ptr(self.tcx, ty_a, mt_b),
|
||||
},
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
@ -1033,10 +1039,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
// regionck knows that the region for `a` must be valid here.
|
||||
if is_ref {
|
||||
self.unify_and(a_unsafe, b, |target| {
|
||||
vec![Adjustment { kind: Adjust::Deref(None), target: mt_a.ty }, Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::RawPtr(mutbl_b)),
|
||||
target,
|
||||
}]
|
||||
vec![
|
||||
Adjustment { kind: Adjust::Deref(None), target: mt_a.ty },
|
||||
Adjustment { kind: Adjust::Borrow(AutoBorrow::RawPtr(mutbl_b)), target },
|
||||
]
|
||||
})
|
||||
} else if mt_a.mutbl != mutbl_b {
|
||||
self.unify_and(a_unsafe, b, simple(Adjust::Pointer(PointerCoercion::MutToConstPointer)))
|
||||
@ -1288,10 +1294,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
_ => span_bug!(new.span, "should not try to coerce a {new_ty} to a fn pointer"),
|
||||
};
|
||||
for expr in exprs.iter().map(|e| e.as_coercion_site()) {
|
||||
self.apply_adjustments(expr, vec![Adjustment {
|
||||
kind: prev_adjustment.clone(),
|
||||
target: fn_ptr,
|
||||
}]);
|
||||
self.apply_adjustments(
|
||||
expr,
|
||||
vec![Adjustment { kind: prev_adjustment.clone(), target: fn_ptr }],
|
||||
);
|
||||
}
|
||||
self.apply_adjustments(new, vec![Adjustment { kind: next_adjustment, target: fn_ptr }]);
|
||||
return Ok(fn_ptr);
|
||||
|
@ -84,10 +84,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
let adj_ty = self.next_ty_var(expr.span);
|
||||
self.apply_adjustments(expr, vec![Adjustment {
|
||||
kind: Adjust::NeverToAny,
|
||||
target: adj_ty,
|
||||
}]);
|
||||
self.apply_adjustments(
|
||||
expr,
|
||||
vec![Adjustment { kind: Adjust::NeverToAny, target: adj_ty }],
|
||||
);
|
||||
ty = adj_ty;
|
||||
}
|
||||
|
||||
|
@ -290,10 +290,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
let autoborrow_mut = adj.iter().any(|adj| {
|
||||
matches!(adj, &Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })),
|
||||
..
|
||||
})
|
||||
matches!(
|
||||
adj,
|
||||
&Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })),
|
||||
..
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
match self.typeck_results.borrow_mut().adjustments_mut().entry(expr.hir_id) {
|
||||
@ -972,11 +975,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let mut sp = MultiSpan::from_span(path_segment.ident.span);
|
||||
sp.push_span_label(
|
||||
path_segment.ident.span,
|
||||
format!("this call modifies {} in-place", match rcvr.kind {
|
||||
ExprKind::Path(QPath::Resolved(None, hir::Path { segments: [segment], .. })) =>
|
||||
format!("`{}`", segment.ident),
|
||||
_ => "its receiver".to_string(),
|
||||
}),
|
||||
format!(
|
||||
"this call modifies {} in-place",
|
||||
match rcvr.kind {
|
||||
ExprKind::Path(QPath::Resolved(
|
||||
None,
|
||||
hir::Path { segments: [segment], .. },
|
||||
)) => format!("`{}`", segment.ident),
|
||||
_ => "its receiver".to_string(),
|
||||
}
|
||||
),
|
||||
);
|
||||
|
||||
let modifies_rcvr_note =
|
||||
|
@ -1988,17 +1988,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expr.kind,
|
||||
hir::ExprKind::Call(
|
||||
hir::Expr {
|
||||
kind: hir::ExprKind::Path(hir::QPath::Resolved(None, hir::Path {
|
||||
res: Res::Def(hir::def::DefKind::Ctor(_, _), _),
|
||||
..
|
||||
},)),
|
||||
kind: hir::ExprKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
hir::Path { res: Res::Def(hir::def::DefKind::Ctor(_, _), _), .. },
|
||||
)),
|
||||
..
|
||||
},
|
||||
..,
|
||||
) | hir::ExprKind::Path(hir::QPath::Resolved(None, hir::Path {
|
||||
res: Res::Def(hir::def::DefKind::Ctor(_, _), _),
|
||||
..
|
||||
},)),
|
||||
) | hir::ExprKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
hir::Path { res: Res::Def(hir::def::DefKind::Ctor(_, _), _), .. },
|
||||
)),
|
||||
);
|
||||
|
||||
let (article, kind, variant, sugg_operator) =
|
||||
|
@ -3922,11 +3922,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let all_suggs = candidate_strs.iter().map(|cand| {
|
||||
let suggestion = format!("{} {cand}", match introducer {
|
||||
Introducer::Plus => " +",
|
||||
Introducer::Colon => ":",
|
||||
Introducer::Nothing => "",
|
||||
},);
|
||||
let suggestion = format!(
|
||||
"{} {cand}",
|
||||
match introducer {
|
||||
Introducer::Plus => " +",
|
||||
Introducer::Colon => ":",
|
||||
Introducer::Nothing => "",
|
||||
},
|
||||
);
|
||||
|
||||
let mut suggs = vec![];
|
||||
|
||||
|
@ -918,13 +918,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let opname = Ident::with_dummy_span(opname);
|
||||
let (opt_rhs_expr, opt_rhs_ty) = opt_rhs.unzip();
|
||||
let cause = self.cause(span, ObligationCauseCode::BinOp {
|
||||
lhs_hir_id: lhs_expr.hir_id,
|
||||
rhs_hir_id: opt_rhs_expr.map(|expr| expr.hir_id),
|
||||
rhs_span: opt_rhs_expr.map(|expr| expr.span),
|
||||
rhs_is_lit: opt_rhs_expr.is_some_and(|expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
|
||||
output_ty: expected.only_has_type(self),
|
||||
});
|
||||
let cause = self.cause(
|
||||
span,
|
||||
ObligationCauseCode::BinOp {
|
||||
lhs_hir_id: lhs_expr.hir_id,
|
||||
rhs_hir_id: opt_rhs_expr.map(|expr| expr.hir_id),
|
||||
rhs_span: opt_rhs_expr.map(|expr| expr.span),
|
||||
rhs_is_lit: opt_rhs_expr
|
||||
.is_some_and(|expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
|
||||
output_ty: expected.only_has_type(self),
|
||||
},
|
||||
);
|
||||
|
||||
let method =
|
||||
self.lookup_method_in_trait(cause.clone(), opname, trait_did, lhs_ty, opt_rhs_ty);
|
||||
|
@ -30,10 +30,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let ok = self.try_overloaded_deref(expr.span, oprnd_ty)?;
|
||||
let method = self.register_infer_ok_obligations(ok);
|
||||
if let ty::Ref(_, _, hir::Mutability::Not) = method.sig.inputs()[0].kind() {
|
||||
self.apply_adjustments(oprnd_expr, vec![Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)),
|
||||
target: method.sig.inputs()[0],
|
||||
}]);
|
||||
self.apply_adjustments(
|
||||
oprnd_expr,
|
||||
vec![Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)),
|
||||
target: method.sig.inputs()[0],
|
||||
}],
|
||||
);
|
||||
} else {
|
||||
span_bug!(expr.span, "input to deref is not a ref?");
|
||||
}
|
||||
|
@ -288,11 +288,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
bug!();
|
||||
};
|
||||
let place = self.place_for_root_variable(closure_def_id, local_id);
|
||||
delegate.capture_information.push((place, ty::CaptureInfo {
|
||||
capture_kind_expr_id: Some(init.hir_id),
|
||||
path_expr_id: Some(init.hir_id),
|
||||
capture_kind: UpvarCapture::ByValue,
|
||||
}));
|
||||
delegate.capture_information.push((
|
||||
place,
|
||||
ty::CaptureInfo {
|
||||
capture_kind_expr_id: Some(init.hir_id),
|
||||
path_expr_id: Some(init.hir_id),
|
||||
capture_kind: UpvarCapture::ByValue,
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,11 +382,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if let UpvarArgs::CoroutineClosure(args) = args
|
||||
&& !args.references_error()
|
||||
{
|
||||
let closure_env_region: ty::Region<'_> =
|
||||
ty::Region::new_bound(self.tcx, ty::INNERMOST, ty::BoundRegion {
|
||||
var: ty::BoundVar::ZERO,
|
||||
kind: ty::BoundRegionKind::ClosureEnv,
|
||||
});
|
||||
let closure_env_region: ty::Region<'_> = ty::Region::new_bound(
|
||||
self.tcx,
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::ClosureEnv },
|
||||
);
|
||||
|
||||
let num_args = args
|
||||
.as_coroutine_closure()
|
||||
@ -2009,11 +2012,14 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> {
|
||||
let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else { return };
|
||||
assert_eq!(self.closure_def_id, upvar_id.closure_expr_id);
|
||||
|
||||
self.capture_information.push((place_with_id.place.clone(), ty::CaptureInfo {
|
||||
capture_kind_expr_id: Some(diag_expr_id),
|
||||
path_expr_id: Some(diag_expr_id),
|
||||
capture_kind: ty::UpvarCapture::ByValue,
|
||||
}));
|
||||
self.capture_information.push((
|
||||
place_with_id.place.clone(),
|
||||
ty::CaptureInfo {
|
||||
capture_kind_expr_id: Some(diag_expr_id),
|
||||
path_expr_id: Some(diag_expr_id),
|
||||
capture_kind: ty::UpvarCapture::ByValue,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
@ -2040,11 +2046,14 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> {
|
||||
capture_kind = ty::UpvarCapture::ByRef(ty::BorrowKind::Immutable);
|
||||
}
|
||||
|
||||
self.capture_information.push((place, ty::CaptureInfo {
|
||||
capture_kind_expr_id: Some(diag_expr_id),
|
||||
path_expr_id: Some(diag_expr_id),
|
||||
capture_kind,
|
||||
}));
|
||||
self.capture_information.push((
|
||||
place,
|
||||
ty::CaptureInfo {
|
||||
capture_kind_expr_id: Some(diag_expr_id),
|
||||
path_expr_id: Some(diag_expr_id),
|
||||
capture_kind,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
|
@ -107,11 +107,10 @@ const LABELS_FN_IN_TRAIT: &[&[&str]] =
|
||||
const LABELS_HIR_ONLY: &[&[&str]] = &[BASE_HIR];
|
||||
|
||||
/// Impl `DepNode`s.
|
||||
const LABELS_TRAIT: &[&[&str]] = &[BASE_HIR, &[
|
||||
label_strs::associated_item_def_ids,
|
||||
label_strs::predicates_of,
|
||||
label_strs::generics_of,
|
||||
]];
|
||||
const LABELS_TRAIT: &[&[&str]] = &[
|
||||
BASE_HIR,
|
||||
&[label_strs::associated_item_def_ids, label_strs::predicates_of, label_strs::generics_of],
|
||||
];
|
||||
|
||||
/// Impl `DepNode`s.
|
||||
const LABELS_IMPL: &[&[&str]] = &[BASE_HIR, BASE_IMPL];
|
||||
|
@ -118,11 +118,10 @@ fn chunked_bitset() {
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
let mut b1 = ChunkedBitSet::<usize>::new_empty(1);
|
||||
assert_eq!(b1, ChunkedBitSet {
|
||||
domain_size: 1,
|
||||
chunks: Box::new([Zeros(1)]),
|
||||
marker: PhantomData
|
||||
});
|
||||
assert_eq!(
|
||||
b1,
|
||||
ChunkedBitSet { domain_size: 1, chunks: Box::new([Zeros(1)]), marker: PhantomData }
|
||||
);
|
||||
|
||||
b1.assert_valid();
|
||||
assert!(!b1.contains(0));
|
||||
@ -141,11 +140,10 @@ fn chunked_bitset() {
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
let mut b100 = ChunkedBitSet::<usize>::new_filled(100);
|
||||
assert_eq!(b100, ChunkedBitSet {
|
||||
domain_size: 100,
|
||||
chunks: Box::new([Ones(100)]),
|
||||
marker: PhantomData
|
||||
});
|
||||
assert_eq!(
|
||||
b100,
|
||||
ChunkedBitSet { domain_size: 100, chunks: Box::new([Ones(100)]), marker: PhantomData }
|
||||
);
|
||||
|
||||
b100.assert_valid();
|
||||
for i in 0..100 {
|
||||
@ -160,17 +158,20 @@ fn chunked_bitset() {
|
||||
);
|
||||
assert_eq!(b100.count(), 97);
|
||||
assert!(!b100.contains(20) && b100.contains(30) && !b100.contains(99) && b100.contains(50));
|
||||
assert_eq!(b100.chunks(), vec![Mixed(
|
||||
100,
|
||||
97,
|
||||
#[rustfmt::skip]
|
||||
assert_eq!(
|
||||
b100.chunks(),
|
||||
vec![Mixed(
|
||||
100,
|
||||
97,
|
||||
#[rustfmt::skip]
|
||||
Rc::new([
|
||||
0b11111111_11111111_11111110_11111111_11111111_11101111_11111111_11111111,
|
||||
0b00000000_00000000_00000000_00000111_11111111_11111111_11111111_11111111,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
])
|
||||
)],);
|
||||
)],
|
||||
);
|
||||
b100.assert_valid();
|
||||
let mut num_removed = 0;
|
||||
for i in 0..100 {
|
||||
@ -185,11 +186,14 @@ fn chunked_bitset() {
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
let mut b2548 = ChunkedBitSet::<usize>::new_empty(2548);
|
||||
assert_eq!(b2548, ChunkedBitSet {
|
||||
domain_size: 2548,
|
||||
chunks: Box::new([Zeros(2048), Zeros(500)]),
|
||||
marker: PhantomData,
|
||||
});
|
||||
assert_eq!(
|
||||
b2548,
|
||||
ChunkedBitSet {
|
||||
domain_size: 2548,
|
||||
chunks: Box::new([Zeros(2048), Zeros(500)]),
|
||||
marker: PhantomData,
|
||||
}
|
||||
);
|
||||
|
||||
b2548.assert_valid();
|
||||
b2548.insert(14);
|
||||
@ -206,11 +210,14 @@ fn chunked_bitset() {
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
let mut b4096 = ChunkedBitSet::<usize>::new_empty(4096);
|
||||
assert_eq!(b4096, ChunkedBitSet {
|
||||
domain_size: 4096,
|
||||
chunks: Box::new([Zeros(2048), Zeros(2048)]),
|
||||
marker: PhantomData,
|
||||
});
|
||||
assert_eq!(
|
||||
b4096,
|
||||
ChunkedBitSet {
|
||||
domain_size: 4096,
|
||||
chunks: Box::new([Zeros(2048), Zeros(2048)]),
|
||||
marker: PhantomData,
|
||||
}
|
||||
);
|
||||
|
||||
b4096.assert_valid();
|
||||
for i in 0..4096 {
|
||||
@ -240,11 +247,14 @@ fn chunked_bitset() {
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
let mut b10000 = ChunkedBitSet::<usize>::new_empty(10000);
|
||||
assert_eq!(b10000, ChunkedBitSet {
|
||||
domain_size: 10000,
|
||||
chunks: Box::new([Zeros(2048), Zeros(2048), Zeros(2048), Zeros(2048), Zeros(1808),]),
|
||||
marker: PhantomData,
|
||||
});
|
||||
assert_eq!(
|
||||
b10000,
|
||||
ChunkedBitSet {
|
||||
domain_size: 10000,
|
||||
chunks: Box::new([Zeros(2048), Zeros(2048), Zeros(2048), Zeros(2048), Zeros(1808),]),
|
||||
marker: PhantomData,
|
||||
}
|
||||
);
|
||||
|
||||
b10000.assert_valid();
|
||||
assert!(b10000.insert(3000) && b10000.insert(5000));
|
||||
|
@ -29,21 +29,19 @@ fn index_size_is_optimized() {
|
||||
#[test]
|
||||
fn range_iterator_iterates_forwards() {
|
||||
let range = MyIdx::from_u32(1)..MyIdx::from_u32(4);
|
||||
assert_eq!(range.collect::<Vec<_>>(), [
|
||||
MyIdx::from_u32(1),
|
||||
MyIdx::from_u32(2),
|
||||
MyIdx::from_u32(3)
|
||||
]);
|
||||
assert_eq!(
|
||||
range.collect::<Vec<_>>(),
|
||||
[MyIdx::from_u32(1), MyIdx::from_u32(2), MyIdx::from_u32(3)]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn range_iterator_iterates_backwards() {
|
||||
let range = MyIdx::from_u32(1)..MyIdx::from_u32(4);
|
||||
assert_eq!(range.rev().collect::<Vec<_>>(), [
|
||||
MyIdx::from_u32(3),
|
||||
MyIdx::from_u32(2),
|
||||
MyIdx::from_u32(1)
|
||||
]);
|
||||
assert_eq!(
|
||||
range.rev().collect::<Vec<_>>(),
|
||||
[MyIdx::from_u32(3), MyIdx::from_u32(2), MyIdx::from_u32(1)]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -100,16 +100,20 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
) {
|
||||
debug!(?sup_type, ?sub_region, ?cause);
|
||||
let origin = SubregionOrigin::from_obligation_cause(cause, || {
|
||||
infer::RelateParamBound(cause.span, sup_type, match cause.code().peel_derives() {
|
||||
ObligationCauseCode::WhereClause(_, span)
|
||||
| ObligationCauseCode::WhereClauseInExpr(_, span, ..)
|
||||
| ObligationCauseCode::OpaqueTypeBound(span, _)
|
||||
if !span.is_dummy() =>
|
||||
{
|
||||
Some(*span)
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
infer::RelateParamBound(
|
||||
cause.span,
|
||||
sup_type,
|
||||
match cause.code().peel_derives() {
|
||||
ObligationCauseCode::WhereClause(_, span)
|
||||
| ObligationCauseCode::WhereClauseInExpr(_, span, ..)
|
||||
| ObligationCauseCode::OpaqueTypeBound(span, _)
|
||||
if !span.is_dummy() =>
|
||||
{
|
||||
Some(*span)
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
)
|
||||
});
|
||||
|
||||
self.register_region_obligation(RegionObligation { sup_type, sub_region, origin });
|
||||
|
@ -34,22 +34,22 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
|
||||
let delegate = FnMutDelegate {
|
||||
regions: &mut |br: ty::BoundRegion| {
|
||||
ty::Region::new_placeholder(self.tcx, ty::PlaceholderRegion {
|
||||
universe: next_universe,
|
||||
bound: br,
|
||||
})
|
||||
ty::Region::new_placeholder(
|
||||
self.tcx,
|
||||
ty::PlaceholderRegion { universe: next_universe, bound: br },
|
||||
)
|
||||
},
|
||||
types: &mut |bound_ty: ty::BoundTy| {
|
||||
Ty::new_placeholder(self.tcx, ty::PlaceholderType {
|
||||
universe: next_universe,
|
||||
bound: bound_ty,
|
||||
})
|
||||
Ty::new_placeholder(
|
||||
self.tcx,
|
||||
ty::PlaceholderType { universe: next_universe, bound: bound_ty },
|
||||
)
|
||||
},
|
||||
consts: &mut |bound_var: ty::BoundVar| {
|
||||
ty::Const::new_placeholder(self.tcx, ty::PlaceholderConst {
|
||||
universe: next_universe,
|
||||
bound: bound_var,
|
||||
})
|
||||
ty::Const::new_placeholder(
|
||||
self.tcx,
|
||||
ty::PlaceholderConst { universe: next_universe, bound: bound_var },
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -45,12 +45,15 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
|
||||
cause: ObligationCause<'tcx>,
|
||||
) {
|
||||
let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]);
|
||||
self.register_predicate_obligation(infcx, Obligation {
|
||||
cause,
|
||||
recursion_depth: 0,
|
||||
param_env,
|
||||
predicate: trait_ref.upcast(infcx.tcx),
|
||||
});
|
||||
self.register_predicate_obligation(
|
||||
infcx,
|
||||
Obligation {
|
||||
cause,
|
||||
recursion_depth: 0,
|
||||
param_env,
|
||||
predicate: trait_ref.upcast(infcx.tcx),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn register_predicate_obligation(
|
||||
|
@ -193,10 +193,10 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
|
||||
if result.must_apply_considering_regions() {
|
||||
ty.obligations = PredicateObligations::new();
|
||||
}
|
||||
map.insert(key, ProjectionCacheEntry::NormalizedTerm {
|
||||
ty,
|
||||
complete: Some(result),
|
||||
});
|
||||
map.insert(
|
||||
key,
|
||||
ProjectionCacheEntry::NormalizedTerm { ty, complete: Some(result) },
|
||||
);
|
||||
}
|
||||
ref value => {
|
||||
// Type inference could "strand behind" old cache entries. Leave
|
||||
|
@ -770,11 +770,14 @@ fn test_unstable_options_tracking_hash() {
|
||||
})
|
||||
);
|
||||
tracked!(codegen_backend, Some("abc".to_string()));
|
||||
tracked!(coverage_options, CoverageOptions {
|
||||
level: CoverageLevel::Mcdc,
|
||||
no_mir_spans: true,
|
||||
discard_all_spans_in_codegen: true
|
||||
});
|
||||
tracked!(
|
||||
coverage_options,
|
||||
CoverageOptions {
|
||||
level: CoverageLevel::Mcdc,
|
||||
no_mir_spans: true,
|
||||
discard_all_spans_in_codegen: true
|
||||
}
|
||||
);
|
||||
tracked!(crate_attr, vec!["abc".to_string()]);
|
||||
tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
|
||||
tracked!(debug_info_for_profiling, true);
|
||||
|
@ -131,7 +131,9 @@ fn check_lexing(src: &str, expect: Expect) {
|
||||
|
||||
#[test]
|
||||
fn smoke_test() {
|
||||
check_lexing("/* my source file */ fn main() { println!(\"zebra\"); }\n", expect![[r#"
|
||||
check_lexing(
|
||||
"/* my source file */ fn main() { println!(\"zebra\"); }\n",
|
||||
expect![[r#"
|
||||
Token { kind: BlockComment { doc_style: None, terminated: true }, len: 20 }
|
||||
Token { kind: Whitespace, len: 1 }
|
||||
Token { kind: Ident, len: 2 }
|
||||
@ -151,7 +153,8 @@ fn smoke_test() {
|
||||
Token { kind: Whitespace, len: 1 }
|
||||
Token { kind: CloseBrace, len: 1 }
|
||||
Token { kind: Whitespace, len: 1 }
|
||||
"#]])
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -194,35 +197,47 @@ fn comment_flavors() {
|
||||
|
||||
#[test]
|
||||
fn nested_block_comments() {
|
||||
check_lexing("/* /* */ */'a'", expect![[r#"
|
||||
check_lexing(
|
||||
"/* /* */ */'a'",
|
||||
expect![[r#"
|
||||
Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 }
|
||||
Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
|
||||
"#]])
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn characters() {
|
||||
check_lexing("'a' ' ' '\\n'", expect![[r#"
|
||||
check_lexing(
|
||||
"'a' ' ' '\\n'",
|
||||
expect![[r#"
|
||||
Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
|
||||
Token { kind: Whitespace, len: 1 }
|
||||
Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 }
|
||||
Token { kind: Whitespace, len: 1 }
|
||||
Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 4 }, len: 4 }
|
||||
"#]]);
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lifetime() {
|
||||
check_lexing("'abc", expect![[r#"
|
||||
check_lexing(
|
||||
"'abc",
|
||||
expect![[r#"
|
||||
Token { kind: Lifetime { starts_with_number: false }, len: 4 }
|
||||
"#]]);
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn raw_string() {
|
||||
check_lexing("r###\"\"#a\\b\x00c\"\"###", expect![[r#"
|
||||
check_lexing(
|
||||
"r###\"\"#a\\b\x00c\"\"###",
|
||||
expect![[r#"
|
||||
Token { kind: Literal { kind: RawStr { n_hashes: Some(3) }, suffix_start: 17 }, len: 17 }
|
||||
"#]])
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -108,12 +108,15 @@ fn test_unescape_str_warn() {
|
||||
check("\\\n", &[]);
|
||||
check("\\\n ", &[]);
|
||||
|
||||
check("\\\n \u{a0} x", &[
|
||||
(0..5, Err(EscapeError::UnskippedWhitespaceWarning)),
|
||||
(3..5, Ok('\u{a0}')),
|
||||
(5..6, Ok(' ')),
|
||||
(6..7, Ok('x')),
|
||||
]);
|
||||
check(
|
||||
"\\\n \u{a0} x",
|
||||
&[
|
||||
(0..5, Err(EscapeError::UnskippedWhitespaceWarning)),
|
||||
(3..5, Ok('\u{a0}')),
|
||||
(5..6, Ok(' ')),
|
||||
(6..7, Ok('x')),
|
||||
],
|
||||
);
|
||||
check("\\\n \n x", &[(0..7, Err(EscapeError::MultipleSkippedLinesWarning)), (7..8, Ok('x'))]);
|
||||
}
|
||||
|
||||
|
@ -102,10 +102,11 @@ impl EarlyLintPass for WhileTrue {
|
||||
"{}loop",
|
||||
label.map_or_else(String::new, |label| format!("{}: ", label.ident,))
|
||||
);
|
||||
cx.emit_span_lint(WHILE_TRUE, condition_span, BuiltinWhileTrue {
|
||||
suggestion: condition_span,
|
||||
replace,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
WHILE_TRUE,
|
||||
condition_span,
|
||||
BuiltinWhileTrue { suggestion: condition_span, replace },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -421,10 +422,11 @@ impl MissingDoc {
|
||||
let attrs = cx.tcx.hir().attrs(cx.tcx.local_def_id_to_hir_id(def_id));
|
||||
let has_doc = attrs.iter().any(has_doc);
|
||||
if !has_doc {
|
||||
cx.emit_span_lint(MISSING_DOCS, cx.tcx.def_span(def_id), BuiltinMissingDoc {
|
||||
article,
|
||||
desc,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
MISSING_DOCS,
|
||||
cx.tcx.def_span(def_id),
|
||||
BuiltinMissingDoc { article, desc },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -706,10 +708,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
|
||||
.next()
|
||||
.is_some();
|
||||
if !has_impl {
|
||||
cx.emit_span_lint(MISSING_DEBUG_IMPLEMENTATIONS, item.span, BuiltinMissingDebugImpl {
|
||||
tcx: cx.tcx,
|
||||
def_id: debug,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
MISSING_DEBUG_IMPLEMENTATIONS,
|
||||
item.span,
|
||||
BuiltinMissingDebugImpl { tcx: cx.tcx, def_id: debug },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -831,12 +834,11 @@ impl EarlyLintPass for DeprecatedAttr {
|
||||
BuiltinDeprecatedAttrLinkSuggestion::Default { suggestion: attr.span }
|
||||
}
|
||||
};
|
||||
cx.emit_span_lint(DEPRECATED, attr.span, BuiltinDeprecatedAttrLink {
|
||||
name,
|
||||
reason,
|
||||
link,
|
||||
suggestion,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
DEPRECATED,
|
||||
attr.span,
|
||||
BuiltinDeprecatedAttrLink { name, reason, link, suggestion },
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -874,11 +876,11 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &
|
||||
BuiltinUnusedDocCommentSub::BlockHelp
|
||||
}
|
||||
};
|
||||
cx.emit_span_lint(UNUSED_DOC_COMMENTS, span, BuiltinUnusedDocComment {
|
||||
kind: node_kind,
|
||||
label: node_span,
|
||||
sub,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
UNUSED_DOC_COMMENTS,
|
||||
span,
|
||||
BuiltinUnusedDocComment { kind: node_kind, label: node_span, sub },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1008,9 +1010,11 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
|
||||
match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {}
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
|
||||
cx.emit_span_lint(NO_MANGLE_GENERIC_ITEMS, span, BuiltinNoMangleGeneric {
|
||||
suggestion: no_mangle_attr.span,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
NO_MANGLE_GENERIC_ITEMS,
|
||||
span,
|
||||
BuiltinNoMangleGeneric { suggestion: no_mangle_attr.span },
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1037,9 +1041,11 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
|
||||
|
||||
// Const items do not refer to a particular location in memory, and therefore
|
||||
// don't have anything to attach a symbol to
|
||||
cx.emit_span_lint(NO_MANGLE_CONST_ITEMS, it.span, BuiltinConstNoMangle {
|
||||
suggestion,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
NO_MANGLE_CONST_ITEMS,
|
||||
it.span,
|
||||
BuiltinConstNoMangle { suggestion },
|
||||
);
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Impl(hir::Impl { generics, items, .. }) => {
|
||||
@ -1305,12 +1311,16 @@ impl UnreachablePub {
|
||||
applicability = Applicability::MaybeIncorrect;
|
||||
}
|
||||
let def_span = cx.tcx.def_span(def_id);
|
||||
cx.emit_span_lint(UNREACHABLE_PUB, def_span, BuiltinUnreachablePub {
|
||||
what,
|
||||
new_vis,
|
||||
suggestion: (vis_span, applicability),
|
||||
help: exportable,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
UNREACHABLE_PUB,
|
||||
def_span,
|
||||
BuiltinUnreachablePub {
|
||||
what,
|
||||
new_vis,
|
||||
suggestion: (vis_span, applicability),
|
||||
help: exportable,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1454,24 +1464,32 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
|
||||
let enable_feat_help = cx.tcx.sess.is_nightly_build();
|
||||
|
||||
if let [.., label_sp] = *where_spans {
|
||||
cx.emit_span_lint(TYPE_ALIAS_BOUNDS, where_spans, BuiltinTypeAliasBounds {
|
||||
in_where_clause: true,
|
||||
label: label_sp,
|
||||
enable_feat_help,
|
||||
suggestions: vec![(generics.where_clause_span, String::new())],
|
||||
preds: generics.predicates,
|
||||
ty: ty.take(),
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
TYPE_ALIAS_BOUNDS,
|
||||
where_spans,
|
||||
BuiltinTypeAliasBounds {
|
||||
in_where_clause: true,
|
||||
label: label_sp,
|
||||
enable_feat_help,
|
||||
suggestions: vec![(generics.where_clause_span, String::new())],
|
||||
preds: generics.predicates,
|
||||
ty: ty.take(),
|
||||
},
|
||||
);
|
||||
}
|
||||
if let [.., label_sp] = *inline_spans {
|
||||
cx.emit_span_lint(TYPE_ALIAS_BOUNDS, inline_spans, BuiltinTypeAliasBounds {
|
||||
in_where_clause: false,
|
||||
label: label_sp,
|
||||
enable_feat_help,
|
||||
suggestions: inline_sugg,
|
||||
preds: generics.predicates,
|
||||
ty,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
TYPE_ALIAS_BOUNDS,
|
||||
inline_spans,
|
||||
BuiltinTypeAliasBounds {
|
||||
in_where_clause: false,
|
||||
label: label_sp,
|
||||
enable_feat_help,
|
||||
suggestions: inline_sugg,
|
||||
preds: generics.predicates,
|
||||
ty,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1559,10 +1577,11 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
||||
| ty::ClauseKind::HostEffect(..) => continue,
|
||||
};
|
||||
if predicate.is_global() {
|
||||
cx.emit_span_lint(TRIVIAL_BOUNDS, span, BuiltinTrivialBounds {
|
||||
predicate_kind_name,
|
||||
predicate,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
TRIVIAL_BOUNDS,
|
||||
span,
|
||||
BuiltinTrivialBounds { predicate_kind_name, predicate },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1611,12 +1630,16 @@ impl EarlyLintPass for DoubleNegations {
|
||||
&& let ExprKind::Unary(UnOp::Neg, ref inner2) = inner.kind
|
||||
&& !matches!(inner2.kind, ExprKind::Unary(UnOp::Neg, _))
|
||||
{
|
||||
cx.emit_span_lint(DOUBLE_NEGATIONS, expr.span, BuiltinDoubleNegations {
|
||||
add_parens: BuiltinDoubleNegationsAddParens {
|
||||
start_span: inner.span.shrink_to_lo(),
|
||||
end_span: inner.span.shrink_to_hi(),
|
||||
cx.emit_span_lint(
|
||||
DOUBLE_NEGATIONS,
|
||||
expr.span,
|
||||
BuiltinDoubleNegations {
|
||||
add_parens: BuiltinDoubleNegationsAddParens {
|
||||
start_span: inner.span.shrink_to_lo(),
|
||||
end_span: inner.span.shrink_to_hi(),
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1931,12 +1954,11 @@ impl KeywordIdents {
|
||||
return;
|
||||
}
|
||||
|
||||
cx.emit_span_lint(lint, ident.span, BuiltinKeywordIdents {
|
||||
kw: ident,
|
||||
next: edition,
|
||||
suggestion: ident.span,
|
||||
prefix,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
lint,
|
||||
ident.span,
|
||||
BuiltinKeywordIdents { kw: ident, next: edition, suggestion: ident.span, prefix },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2357,11 +2379,11 @@ impl EarlyLintPass for IncompleteInternalFeatures {
|
||||
let help =
|
||||
HAS_MIN_FEATURES.contains(&name).then_some(BuiltinIncompleteFeaturesHelp);
|
||||
|
||||
cx.emit_span_lint(INCOMPLETE_FEATURES, span, BuiltinIncompleteFeatures {
|
||||
name,
|
||||
note,
|
||||
help,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
INCOMPLETE_FEATURES,
|
||||
span,
|
||||
BuiltinIncompleteFeatures { name, note, help },
|
||||
);
|
||||
} else {
|
||||
cx.emit_span_lint(INTERNAL_FEATURES, span, BuiltinInternalFeatures { name });
|
||||
}
|
||||
@ -2684,13 +2706,17 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
|
||||
InitKind::Uninit => fluent::lint_builtin_unpermitted_type_init_uninit,
|
||||
};
|
||||
let sub = BuiltinUnpermittedTypeInitSub { err };
|
||||
cx.emit_span_lint(INVALID_VALUE, expr.span, BuiltinUnpermittedTypeInit {
|
||||
msg,
|
||||
ty: conjured_ty,
|
||||
label: expr.span,
|
||||
sub,
|
||||
tcx: cx.tcx,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
INVALID_VALUE,
|
||||
expr.span,
|
||||
BuiltinUnpermittedTypeInit {
|
||||
msg,
|
||||
ty: conjured_ty,
|
||||
label: expr.span,
|
||||
sub,
|
||||
tcx: cx.tcx,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2776,9 +2802,11 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr {
|
||||
{
|
||||
// `&raw *NULL` is ok.
|
||||
} else {
|
||||
cx.emit_span_lint(DEREF_NULLPTR, expr.span, BuiltinDerefNullptr {
|
||||
label: expr.span,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
DEREF_NULLPTR,
|
||||
expr.span,
|
||||
BuiltinDerefNullptr { label: expr.span },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2995,14 +3023,18 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels {
|
||||
let span = span.unwrap_or(*template_span);
|
||||
match label_kind {
|
||||
AsmLabelKind::Named => {
|
||||
cx.emit_span_lint(NAMED_ASM_LABELS, span, InvalidAsmLabel::Named {
|
||||
missing_precise_span,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
NAMED_ASM_LABELS,
|
||||
span,
|
||||
InvalidAsmLabel::Named { missing_precise_span },
|
||||
);
|
||||
}
|
||||
AsmLabelKind::FormatArg => {
|
||||
cx.emit_span_lint(NAMED_ASM_LABELS, span, InvalidAsmLabel::FormatArg {
|
||||
missing_precise_span,
|
||||
});
|
||||
cx.emit_span_lint(
|
||||
NAMED_ASM_LABELS,
|
||||
span,
|
||||
InvalidAsmLabel::FormatArg { missing_precise_span },
|
||||
);
|
||||
}
|
||||
// the binary asm issue only occurs when using intel syntax on x86 targets
|
||||
AsmLabelKind::Binary
|
||||
@ -3012,10 +3044,11 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels {
|
||||
Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) | None
|
||||
) =>
|
||||
{
|
||||
cx.emit_span_lint(BINARY_ASM_LABELS, span, InvalidAsmLabel::Binary {
|
||||
missing_precise_span,
|
||||
cx.emit_span_lint(
|
||||
BINARY_ASM_LABELS,
|
||||
span,
|
||||
})
|
||||
InvalidAsmLabel::Binary { missing_precise_span, span },
|
||||
)
|
||||
}
|
||||
// No lint on anything other than x86
|
||||
AsmLabelKind::Binary => (),
|
||||
|
@ -233,11 +233,14 @@ impl LintStore {
|
||||
}
|
||||
|
||||
pub fn register_group_alias(&mut self, lint_name: &'static str, alias: &'static str) {
|
||||
self.lint_groups.insert(alias, LintGroup {
|
||||
lint_ids: vec![],
|
||||
is_externally_loaded: false,
|
||||
depr: Some(LintAlias { name: lint_name, silent: true }),
|
||||
});
|
||||
self.lint_groups.insert(
|
||||
alias,
|
||||
LintGroup {
|
||||
lint_ids: vec![],
|
||||
is_externally_loaded: false,
|
||||
depr: Some(LintAlias { name: lint_name, silent: true }),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
pub fn register_group(
|
||||
@ -252,11 +255,14 @@ impl LintStore {
|
||||
.insert(name, LintGroup { lint_ids: to, is_externally_loaded, depr: None })
|
||||
.is_none();
|
||||
if let Some(deprecated) = deprecated_name {
|
||||
self.lint_groups.insert(deprecated, LintGroup {
|
||||
lint_ids: vec![],
|
||||
is_externally_loaded,
|
||||
depr: Some(LintAlias { name, silent: false }),
|
||||
});
|
||||
self.lint_groups.insert(
|
||||
deprecated,
|
||||
LintGroup {
|
||||
lint_ids: vec![],
|
||||
is_externally_loaded,
|
||||
depr: Some(LintAlias { name, silent: false }),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if !new {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user