Skip to content

Commit ec42485

Browse files
committed
Auto merge of rust-lang#73206 - Dylan-DPC:rollup-rha9g8q, r=Dylan-DPC
Rollup of 9 pull requests Successful merges: - rust-lang#72706 (Add windows group to triagebot) - rust-lang#72789 (resolve: Do not suggest imports from the same module in which we are resolving) - rust-lang#72890 (improper ctypes: normalize return types and transparent structs) - rust-lang#72897 (normalize adt fields during structural match checking) - rust-lang#73005 (Don't create impl candidates when obligation contains errors) - rust-lang#73023 (Remove noisy suggestion of hash_map ) - rust-lang#73070 (Add regression test for const generic ICE in rust-lang#72819) - rust-lang#73157 (Don't lose empty `where` clause when pretty-printing) - rust-lang#73184 (Reoder order in which MinGW libs are linked to fix recent breakage) Failed merges: r? @ghost
2 parents 449e8ea + 2b8f1ec commit ec42485

35 files changed

+350
-315
lines changed

src/librustc_ast/ast.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,11 @@ impl Default for Generics {
362362
fn default() -> Generics {
363363
Generics {
364364
params: Vec::new(),
365-
where_clause: WhereClause { predicates: Vec::new(), span: DUMMY_SP },
365+
where_clause: WhereClause {
366+
has_where_token: false,
367+
predicates: Vec::new(),
368+
span: DUMMY_SP,
369+
},
366370
span: DUMMY_SP,
367371
}
368372
}
@@ -371,6 +375,11 @@ impl Default for Generics {
371375
/// A where-clause in a definition.
372376
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
373377
pub struct WhereClause {
378+
/// `true` if we ate a `where` token: this can happen
379+
/// if we parsed no predicates (e.g. `struct Foo where {}
380+
/// This allows us to accurately pretty-print
381+
/// in `nt_to_tokenstream`
382+
pub has_where_token: bool,
374383
pub predicates: Vec<WherePredicate>,
375384
pub span: Span,
376385
}

src/librustc_ast/mut_visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ pub fn noop_visit_generics<T: MutVisitor>(generics: &mut Generics, vis: &mut T)
786786
}
787787

788788
pub fn noop_visit_where_clause<T: MutVisitor>(wc: &mut WhereClause, vis: &mut T) {
789-
let WhereClause { predicates, span } = wc;
789+
let WhereClause { has_where_token: _, predicates, span } = wc;
790790
visit_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
791791
vis.visit_span(span);
792792
}

src/librustc_ast_pretty/pprust.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -2593,7 +2593,7 @@ impl<'a> State<'a> {
25932593
}
25942594

25952595
crate fn print_where_clause(&mut self, where_clause: &ast::WhereClause) {
2596-
if where_clause.predicates.is_empty() {
2596+
if where_clause.predicates.is_empty() && !where_clause.has_where_token {
25972597
return;
25982598
}
25992599

@@ -2739,7 +2739,11 @@ impl<'a> State<'a> {
27392739
}
27402740
let generics = ast::Generics {
27412741
params: Vec::new(),
2742-
where_clause: ast::WhereClause { predicates: Vec::new(), span: rustc_span::DUMMY_SP },
2742+
where_clause: ast::WhereClause {
2743+
has_where_token: false,
2744+
predicates: Vec::new(),
2745+
span: rustc_span::DUMMY_SP,
2746+
},
27432747
span: rustc_span::DUMMY_SP,
27442748
};
27452749
let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() };

src/librustc_builtin_macros/deriving/generic/ty.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,11 @@ fn mk_ty_param(
216216
}
217217

218218
fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
219-
Generics { params, where_clause: ast::WhereClause { predicates: Vec::new(), span }, span }
219+
Generics {
220+
params,
221+
where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), span },
222+
span,
223+
}
220224
}
221225

222226
/// Lifetimes and bounds on type parameters

src/librustc_lint/types.rs

+60-40
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use rustc_attr as attr;
66
use rustc_data_structures::fx::FxHashSet;
77
use rustc_errors::Applicability;
88
use rustc_hir as hir;
9-
use rustc_hir::def_id::DefId;
109
use rustc_hir::{is_range_literal, ExprKind, Node};
1110
use rustc_index::vec::Idx;
1211
use rustc_middle::mir::interpret::{sign_extend, truncate};
@@ -511,10 +510,6 @@ enum FfiResult<'tcx> {
511510
FfiUnsafe { ty: Ty<'tcx>, reason: &'static str, help: Option<&'static str> },
512511
}
513512

514-
fn is_zst<'tcx>(tcx: TyCtxt<'tcx>, did: DefId, ty: Ty<'tcx>) -> bool {
515-
tcx.layout_of(tcx.param_env(did).and(ty)).map(|layout| layout.is_zst()).unwrap_or(false)
516-
}
517-
518513
fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
519514
match ty.kind {
520515
ty::FnPtr(_) => true,
@@ -523,7 +518,7 @@ fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
523518
for field in field_def.all_fields() {
524519
let field_ty =
525520
tcx.normalize_erasing_regions(ParamEnv::reveal_all(), field.ty(tcx, substs));
526-
if is_zst(tcx, field.did, field_ty) {
521+
if field_ty.is_zst(tcx, field.did) {
527522
continue;
528523
}
529524

@@ -653,32 +648,43 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
653648
};
654649
}
655650

656-
// We can't completely trust repr(C) and repr(transparent) markings;
657-
// make sure the fields are actually safe.
658-
let mut all_phantom = true;
659-
for field in &def.non_enum_variant().fields {
660-
let field_ty = cx.normalize_erasing_regions(
661-
ParamEnv::reveal_all(),
662-
field.ty(cx, substs),
663-
);
664-
// repr(transparent) types are allowed to have arbitrary ZSTs, not just
665-
// PhantomData -- skip checking all ZST fields
666-
if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
667-
continue;
651+
if def.repr.transparent() {
652+
// Can assume that only one field is not a ZST, so only check
653+
// that field's type for FFI-safety.
654+
if let Some(field) =
655+
def.transparent_newtype_field(cx, self.cx.param_env)
656+
{
657+
let field_ty = cx.normalize_erasing_regions(
658+
self.cx.param_env,
659+
field.ty(cx, substs),
660+
);
661+
self.check_type_for_ffi(cache, field_ty)
662+
} else {
663+
FfiSafe
668664
}
669-
let r = self.check_type_for_ffi(cache, field_ty);
670-
match r {
671-
FfiSafe => {
672-
all_phantom = false;
673-
}
674-
FfiPhantom(..) => {}
675-
FfiUnsafe { .. } => {
676-
return r;
665+
} else {
666+
// We can't completely trust repr(C) markings; make sure the fields are
667+
// actually safe.
668+
let mut all_phantom = true;
669+
for field in &def.non_enum_variant().fields {
670+
let field_ty = cx.normalize_erasing_regions(
671+
self.cx.param_env,
672+
field.ty(cx, substs),
673+
);
674+
let r = self.check_type_for_ffi(cache, field_ty);
675+
match r {
676+
FfiSafe => {
677+
all_phantom = false;
678+
}
679+
FfiPhantom(..) => {}
680+
FfiUnsafe { .. } => {
681+
return r;
682+
}
677683
}
678684
}
679-
}
680685

681-
if all_phantom { FfiPhantom(ty) } else { FfiSafe }
686+
if all_phantom { FfiPhantom(ty) } else { FfiSafe }
687+
}
682688
}
683689
AdtKind::Union => {
684690
if !def.repr.c() && !def.repr.transparent() {
@@ -708,7 +714,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
708714
);
709715
// repr(transparent) types are allowed to have arbitrary ZSTs, not just
710716
// PhantomData -- skip checking all ZST fields.
711-
if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
717+
if def.repr.transparent() && field_ty.is_zst(cx, field.did) {
712718
continue;
713719
}
714720
let r = self.check_type_for_ffi(cache, field_ty);
@@ -774,7 +780,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
774780
);
775781
// repr(transparent) types are allowed to have arbitrary ZSTs, not
776782
// just PhantomData -- skip checking all ZST fields.
777-
if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
783+
if def.repr.transparent() && field_ty.is_zst(cx, field.did) {
778784
continue;
779785
}
780786
let r = self.check_type_for_ffi(cache, field_ty);
@@ -946,7 +952,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
946952
}
947953
}
948954

949-
fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>, is_static: bool) {
955+
fn check_type_for_ffi_and_report_errors(
956+
&mut self,
957+
sp: Span,
958+
ty: Ty<'tcx>,
959+
is_static: bool,
960+
is_return_type: bool,
961+
) {
950962
// We have to check for opaque types before `normalize_erasing_regions`,
951963
// which will replace opaque types with their underlying concrete type.
952964
if self.check_for_opaque_ty(sp, ty) {
@@ -957,19 +969,29 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
957969
// it is only OK to use this function because extern fns cannot have
958970
// any generic types right now:
959971
let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
960-
// C doesn't really support passing arrays by value.
961-
// The only way to pass an array by value is through a struct.
962-
// So we first test that the top level isn't an array,
963-
// and then recursively check the types inside.
972+
973+
// C doesn't really support passing arrays by value - the only way to pass an array by value
974+
// is through a struct. So, first test that the top level isn't an array, and then
975+
// recursively check the types inside.
964976
if !is_static && self.check_for_array_ty(sp, ty) {
965977
return;
966978
}
967979

980+
// Don't report FFI errors for unit return types. This check exists here, and not in
981+
// `check_foreign_fn` (where it would make more sense) so that normalization has definitely
982+
// happened.
983+
if is_return_type && ty.is_unit() {
984+
return;
985+
}
986+
968987
match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
969988
FfiResult::FfiSafe => {}
970989
FfiResult::FfiPhantom(ty) => {
971990
self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
972991
}
992+
// If `ty` is a `repr(transparent)` newtype, and the non-zero-sized type is a generic
993+
// argument, which after substitution, is `()`, then this branch can be hit.
994+
FfiResult::FfiUnsafe { ty, .. } if is_return_type && ty.is_unit() => return,
973995
FfiResult::FfiUnsafe { ty, reason, help } => {
974996
self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
975997
}
@@ -982,21 +1004,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
9821004
let sig = self.cx.tcx.erase_late_bound_regions(&sig);
9831005

9841006
for (input_ty, input_hir) in sig.inputs().iter().zip(decl.inputs) {
985-
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false);
1007+
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false, false);
9861008
}
9871009

9881010
if let hir::FnRetTy::Return(ref ret_hir) = decl.output {
9891011
let ret_ty = sig.output();
990-
if !ret_ty.is_unit() {
991-
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false);
992-
}
1012+
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false, true);
9931013
}
9941014
}
9951015

9961016
fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
9971017
let def_id = self.cx.tcx.hir().local_def_id(id);
9981018
let ty = self.cx.tcx.type_of(def_id);
999-
self.check_type_for_ffi_and_report_errors(span, ty, true);
1019+
self.check_type_for_ffi_and_report_errors(span, ty, true, false);
10001020
}
10011021
}
10021022

src/librustc_middle/ty/mod.rs

+23
Original file line numberDiff line numberDiff line change
@@ -2390,6 +2390,29 @@ impl<'tcx> AdtDef {
23902390
pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] {
23912391
tcx.adt_sized_constraint(self.did).0
23922392
}
2393+
2394+
/// `repr(transparent)` structs can have a single non-ZST field, this function returns that
2395+
/// field.
2396+
pub fn transparent_newtype_field(
2397+
&self,
2398+
tcx: TyCtxt<'tcx>,
2399+
param_env: ParamEnv<'tcx>,
2400+
) -> Option<&FieldDef> {
2401+
assert!(self.is_struct() && self.repr.transparent());
2402+
2403+
for field in &self.non_enum_variant().fields {
2404+
let field_ty = tcx.normalize_erasing_regions(
2405+
param_env,
2406+
field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.did)),
2407+
);
2408+
2409+
if !field_ty.is_zst(tcx, self.did) {
2410+
return Some(field);
2411+
}
2412+
}
2413+
2414+
None
2415+
}
23932416
}
23942417

23952418
impl<'tcx> FieldDef {

src/librustc_middle/ty/sty.rs

+5
Original file line numberDiff line numberDiff line change
@@ -2186,6 +2186,11 @@ impl<'tcx> TyS<'tcx> {
21862186
}
21872187
}
21882188
}
2189+
2190+
/// Is this a zero-sized type?
2191+
pub fn is_zst(&'tcx self, tcx: TyCtxt<'tcx>, did: DefId) -> bool {
2192+
tcx.layout_of(tcx.param_env(did).and(self)).map(|layout| layout.is_zst()).unwrap_or(false)
2193+
}
21892194
}
21902195

21912196
/// Typed constant value.

src/librustc_parse/parser/generics.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ impl<'a> Parser<'a> {
157157
Ok(ast::Generics {
158158
params,
159159
where_clause: WhereClause {
160+
has_where_token: false,
160161
predicates: Vec::new(),
161162
span: self.prev_token.span.shrink_to_hi(),
162163
},
@@ -170,12 +171,16 @@ impl<'a> Parser<'a> {
170171
/// where T : Trait<U, V> + 'b, 'a : 'b
171172
/// ```
172173
pub(super) fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
173-
let mut where_clause =
174-
WhereClause { predicates: Vec::new(), span: self.prev_token.span.shrink_to_hi() };
174+
let mut where_clause = WhereClause {
175+
has_where_token: false,
176+
predicates: Vec::new(),
177+
span: self.prev_token.span.shrink_to_hi(),
178+
};
175179

176180
if !self.eat_keyword(kw::Where) {
177181
return Ok(where_clause);
178182
}
183+
where_clause.has_where_token = true;
179184
let lo = self.prev_token.span;
180185

181186
// We are considering adding generics to the `where` keyword as an alternative higher-rank

src/librustc_resolve/diagnostics.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ impl<'a> Resolver<'a> {
629629
&mut self,
630630
lookup_ident: Ident,
631631
namespace: Namespace,
632+
parent_scope: &ParentScope<'a>,
632633
start_module: Module<'a>,
633634
crate_name: Ident,
634635
filter_fn: FilterFn,
@@ -655,7 +656,11 @@ impl<'a> Resolver<'a> {
655656
}
656657

657658
// collect results based on the filter function
658-
if ident.name == lookup_ident.name && ns == namespace {
659+
// avoid suggesting anything from the same module in which we are resolving
660+
if ident.name == lookup_ident.name
661+
&& ns == namespace
662+
&& !ptr::eq(in_module, parent_scope.module)
663+
{
659664
let res = name_binding.res();
660665
if filter_fn(res) {
661666
// create the path
@@ -680,7 +685,9 @@ impl<'a> Resolver<'a> {
680685
Res::Def(DefKind::Ctor(..), did) => this.parent(did),
681686
_ => res.opt_def_id(),
682687
};
683-
candidates.push(ImportSuggestion { did, descr: res.descr(), path });
688+
if candidates.iter().all(|v: &ImportSuggestion| v.did != did) {
689+
candidates.push(ImportSuggestion { did, descr: res.descr(), path });
690+
}
684691
}
685692
}
686693
}
@@ -722,6 +729,7 @@ impl<'a> Resolver<'a> {
722729
&mut self,
723730
lookup_ident: Ident,
724731
namespace: Namespace,
732+
parent_scope: &ParentScope<'a>,
725733
filter_fn: FilterFn,
726734
) -> Vec<ImportSuggestion>
727735
where
@@ -730,6 +738,7 @@ impl<'a> Resolver<'a> {
730738
let mut suggestions = self.lookup_import_candidates_from_module(
731739
lookup_ident,
732740
namespace,
741+
parent_scope,
733742
self.graph_root,
734743
Ident::with_dummy_span(kw::Crate),
735744
&filter_fn,
@@ -754,6 +763,7 @@ impl<'a> Resolver<'a> {
754763
suggestions.extend(self.lookup_import_candidates_from_module(
755764
lookup_ident,
756765
namespace,
766+
parent_scope,
757767
crate_root,
758768
ident,
759769
&filter_fn,

src/librustc_resolve/late/diagnostics.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
212212
let ident = path.last().unwrap().ident;
213213
let candidates = self
214214
.r
215-
.lookup_import_candidates(ident, ns, is_expected)
215+
.lookup_import_candidates(ident, ns, &self.parent_scope, is_expected)
216216
.drain(..)
217217
.filter(|ImportSuggestion { did, .. }| {
218218
match (did, res.and_then(|res| res.opt_def_id())) {
@@ -223,7 +223,8 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
223223
.collect::<Vec<_>>();
224224
let crate_def_id = DefId::local(CRATE_DEF_INDEX);
225225
if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) {
226-
let enum_candidates = self.r.lookup_import_candidates(ident, ns, is_enum_variant);
226+
let enum_candidates =
227+
self.r.lookup_import_candidates(ident, ns, &self.parent_scope, is_enum_variant);
227228
let mut enum_candidates = enum_candidates
228229
.iter()
229230
.map(|suggestion| import_candidate_to_enum_paths(&suggestion))

0 commit comments

Comments
 (0)