diff options
79 files changed, 2341 insertions, 1779 deletions
diff --git a/.mailmap b/.mailmap index 8eaf8f16e4b..317a92b8f43 100644 --- a/.mailmap +++ b/.mailmap @@ -7,142 +7,218 @@ Aaron Todd <github@opprobrio.us> Abhishek Chanda <abhishek.becs@gmail.com> Abhishek Chanda <abhishek@cloudscaling.com> +Adolfo Ochagavía <aochagavia92@gmail.com> +Adrien Tétar <adri-from-59@hotmail.fr> Ahmed Charles <ahmedcharles@gmail.com> <acharles@outlook.com> -Aydin Kim <ladinjin@hanmail.net> aydin.kim <aydin.kim@samsung.com> Alex Burka <durka42+github@gmail.com> Alex Burka <aburka@seas.upenn.edu> Alex Lyon <arcterus@mail.com> <Arcterus@mail.com> Alex Newman <posix4e@gmail.com> Alex HotShot Newman <posix4e@gmail.com> Alex Rønne Petersen <alex@lycus.org> +Alexander Light <allight@cs.brown.edu> Alexander Light <scialexlight@gmail.com> +Alexis Beingessner <a.beingessner@gmail.com> Alfie John <alfie@alfie.wtf> Alfie John <alfiej@fastmail.fm> +Anatoly Ikorsky <aikorsky@gmail.com> +Andre Bogus <bogusandre@gmail.com> Andreas Gal <gal@mozilla.com> <andreas.gal@gmail.com> Andrew Kuchev <0coming.soon@gmail.com> Andrew <0coming.soon@gmail.com> Andrew Poelstra <asp11@sfu.ca> <apoelstra@wpsoftware.net> Anton Löfgren <anton.lofgren@gmail.com> <alofgren@op5.com> -Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> arielb1 <arielb1@mail.tau.ac.il> +Areski Belaid <areski@gmail.com> areski <areski@gmail.com> Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> Ariel Ben-Yehuda <ariel.byd@gmail.com> +Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> arielb1 <arielb1@mail.tau.ac.il> Austin Seipp <mad.one@gmail.com> <as@hacks.yi.org> +Aydin Kim <ladinjin@hanmail.net> aydin.kim <aydin.kim@samsung.com> +Barosl Lee <vcs@barosl.com> Barosl LEE <github@barosl.com> Ben Alpert <ben@benalpert.com> <spicyjalapeno@gmail.com> -Ben Sago <ogham@users.noreply.github.com> Ben S <ogham@bsago.me> Ben S <ogham@users.noreply.github.com> +Ben Sago <ogham@users.noreply.github.com> Ben S <ogham@bsago.me> +Ben Sago <ogham@users.noreply.github.com> Ben S <ogham@users.noreply.github.com> Benjamin Jackman <ben@jackman.biz> +Bheesham Persaud <bheesham123@hotmail.com> Bheesham Persaud <bheesham.persaud@live.ca> Björn Steinbrink <bsteinbr@gmail.com> <B.Steinbrink@gmx.de> blake2-ppc <ulrik.sverdrup@gmail.com> <blake2-ppc> Boris Egorov <jightuse@gmail.com> <egorov@linux.com> +Brandon Sanderson <singingboyo@gmail.com> Brandon Sanderson <singingboyo@hotmail.com> +Brett Cannon <brett@python.org> Brett Cannon <brettcannon@users.noreply.github.com> Brian Anderson <banderson@mozilla.com> <andersrb@gmail.com> Brian Dawn <brian.t.dawn@gmail.com> +Brian Leibig <brian@brianleibig.com> Brian Leibig <brian.leibig@gmail.com> Carl-Anton Ingmarsson <mail@carlanton.se> <ca.ingmarsson@gmail.com> Carol (Nichols || Goulding) <carol.nichols@gmail.com> Carol Nichols <carol.nichols@gmail.com> +Carol (Nichols || Goulding) <carol.nichols@gmail.com> Carol Nichols <cnichols@thinkthroughmath.com> Carol Willing <carolcode@willingconsulting.com> Chris C Cerami <chrisccerami@users.noreply.github.com> Chris C Cerami <chrisccerami@gmail.com> Chris Pressey <cpressey@gmail.com> +Chris Thorn <chris@thorn.co> Chris Thorn <thorn@thoughtbot.com> Clark Gaebel <cg.wowus.cg@gmail.com> <cgaebel@mozilla.com> +Clinton Ryan <clint.ryan3@gmail.com> Corey Farwell <coreyf+rust@rwell.org> Corey Farwell <coreyf@rwell.org> Corey Richardson <corey@octayn.net> Elaine "See More" Nemo <corey@octayn.net> +Damien Schoof <damien.schoof@gmail.com> +Daniel Ramos <dan@daramos.com> David Klein <david.klein@baesystemsdetica.com> David Manescu <david.manescu@gmail.com> <dman2626@uni.sydney.edu.au> -Damien Schoof <damien.schoof@gmail.com> +David Ross <daboross@daboross.net> Derek Chiang <derekchiang93@gmail.com> Derek Chiang (Enchi Jiang) <derekchiang93@gmail.com> Diggory Hardy <diggory.hardy@gmail.com> Diggory Hardy <github@dhardy.name> Dylan Braithwaite <dylanbraithwaite1@gmail.com> <mail@dylanb.me> -Eduardo Bautista <me@eduardobautista.com> <mail@eduardobautista.com> +Dzmitry Malyshau <kvarkus@gmail.com> Eduardo Bautista <me@eduardobautista.com> <=> +Eduardo Bautista <me@eduardobautista.com> <mail@eduardobautista.com> Elliott Slaughter <elliottslaughter@gmail.com> <eslaughter@mozilla.com> Elly Fong-Jones <elly@leptoquark.net> Emily Dunham <edunham@mozilla.com> edunham <edunham@mozilla.com> -Eric Holk <eric.holk@gmail.com> <eholk@mozilla.com> Eric Holk <eric.holk@gmail.com> <eholk@cs.indiana.edu> +Eric Holk <eric.holk@gmail.com> <eholk@mozilla.com> Eric Holmes <eric@ejholmes.net> Eric Reed <ecreed@cs.washington.edu> <ereed@mozilla.com> Erick Tryzelaar <erick.tryzelaar@gmail.com> <etryzelaar@iqt.org> Evgeny Sologubov Falco Hirschenberger <falco.hirschenberger@gmail.com> <hirschen@itwm.fhg.de> Felix S. Klock II <pnkfelix@pnkfx.org> Felix S Klock II <pnkfelix@pnkfx.org> +Flaper Fesp <flaper87@gmail.com> +Florian Wilkens <mrfloya_github@outlook.com> Florian Wilkens <floya@live.de> Gareth Daniel Smith <garethdanielsmith@gmail.com> gareth <gareth@gareth-N56VM.(none)> +Gareth Daniel Smith <garethdanielsmith@gmail.com> Gareth Smith <garethdanielsmith@gmail.com> Georges Dubus <georges.dubus@gmail.com> <georges.dubus@compiletoi.net> -Graham Fawcett <fawcett@uwindsor.ca> <graham.fawcett@gmail.com> +Graham Fawcett <graham.fawcett@gmail.com> Graham Fawcett <fawcett@uwindsor.ca> Graydon Hoare <graydon@pobox.com> Graydon Hoare <graydon@mozilla.com> -Heather <heather@cynede.net> <Heather@cynede.net> +Guillaume Gomez <guillaume1.gomez@gmail.com> Heather <heather@cynede.net> <Cynede@Gentoo.org> +Heather <heather@cynede.net> <Heather@cynede.net> +Herman J. Radtke III <herman@hermanradtke.com> Herman J. Radtke III <hermanradtke@gmail.com> Ilyong Cho <ilyoan@gmail.com> +Ivan Ivaschenko <defuz.net@gmail.com> J. J. Weber <jjweber@gmail.com> Jakub Bukaj <jakub@jakub.cc> Jakub Bukaj <jakub@jakub.cc> <jakubw@jakubw.net> +Jakub Bukaj <jakub@jakub.cc> Jakub Bukaj <jakub.bukaj@yahoo.com> James Deng <cnjamesdeng@gmail.com> <cnJamesDeng@gmail.com> James Miller <bladeon@gmail.com> <james@aatch.net> -Jason Orendorff <jorendorff@mozilla.com> <jason@mozmac-2.local> +James Perry <james.austin.perry@gmail.com> +Jason Fager <jfager@gmail.com> Jason Orendorff <jorendorff@mozilla.com> <jason.orendorff@gmail.com> +Jason Orendorff <jorendorff@mozilla.com> <jason@mozmac-2.local> +Jason Toffaletti <toffaletti@gmail.com> Jason Toffaletti <jason@topsy.com> +Jauhien Piatlicki <jauhien@gentoo.org> Jauhien Piatlicki <jpiatlicki@zertisa.com> +Jay True <glacjay@gmail.com> Jeremy Letang <letang.jeremy@gmail.com> -Jihyun Yu <jihyun@nclab.kaist.ac.kr> jihyun <jihyun@nablecomm.com> -Jihyun Yu <jihyun@nclab.kaist.ac.kr> <yjh0502@gmail.com> -Johann Hofmann <mail@johann-hofmann.com> Johann <git@johann-hofmann.com> Johann Hofmann <git@johann-hofmann.com> +Jihyun Yu <j.yu@navercorp.com> <yjh0502@gmail.com> +Jihyun Yu <j.yu@navercorp.com> jihyun <jihyun@nablecomm.com> +Jihyun Yu <j.yu@navercorp.com> Jihyun Yu <jihyun@nclab.kaist.ac.kr> +Johann Hofmann <git@johann-hofmann.com> Johann <git@johann-hofmann.com> John Clements <clements@racket-lang.org> <clements@brinckerhoff.org> John Hodge <acessdev@gmail.com> John Hodge <tpg@mutabah.net> -Jorge Aparicio <japaric@linux.com> <japaricious@gmail.com> +John Kåre Alsaker <john.kare.alsaker@gmail.com> +John Talling <inrustwetrust@users.noreply.github.com> Jonathan Bailey <jbailey@mozilla.com> <jbailey@jbailey-20809.local> +Jonathan S <gereeter@gmail.com> Jonathan S <gereeter+code@gmail.com> +Jorge Aparicio <japaric@linux.com> <japaricious@gmail.com> +Joseph Martin <pythoner6@gmail.com> +João Oliveira <hello@jxs.pt> joaoxsouls <joaoxsouls@gmail.com> Junyoung Cho <june0.cho@samsung.com> Jyun-Yan You <jyyou.tw@gmail.com> <jyyou@cs.nctu.edu.tw> Kang Seonghoon <kang.seonghoon@mearie.org> <public+git@mearie.org> -Keegan McAllister <kmcallister@mozilla.com> <mcallister.keegan@gmail.com> +Keegan McAllister <mcallister.keegan@gmail.com> <kmcallister@mozilla.com> +Kevin Butler <haqkrs@gmail.com> Kyeongwoon Lee <kyeongwoon.lee@samsung.com> -Lee Wondong <wdlee91@gmail.com> Lee Jeffery <leejeffery@gmail.com> Lee Jeffery <lee@leejeffery.co.uk> +Lee Wondong <wdlee91@gmail.com> Lennart Kudling <github@kudling.de> +Léo Testard <leo.testard@gmail.com> Lindsey Kuper <lindsey@composition.al> <lindsey@rockstargirl.org> Lindsey Kuper <lindsey@composition.al> <lkuper@mozilla.com> -Luqman Aden <me@luqman.ca> <laden@mozilla.com> -Luqman Aden <me@luqman.ca> <laden@csclub.uwaterloo.ca> Luke Metz <luke.metz@students.olin.edu> +Luqman Aden <me@luqman.ca> <laden@csclub.uwaterloo.ca> +Luqman Aden <me@luqman.ca> <laden@mozilla.com> Makoto Nakashima <makoto.nksm+github@gmail.com> <makoto.nksm@gmail.com> Makoto Nakashima <makoto.nksm+github@gmail.com> gifnksm <makoto.nksm+github@gmail.com> -Markus Westerlind <marwes91@gmail.com> Markus <marwes91@gmail.com> +Makoto Nakashima <makoto.nksm+github@gmail.com> NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> +Marcell Pardavi <marcell.pardavi@gmail.com> Margaret Meyerhofer <mmeyerho@andrew.cmu.edu> <mmeyerho@andrew> Mark Sinclair <mark.edward.x@gmail.com> Mark Sinclair <mark.edward.x@gmail.com> =Mark Sinclair <=125axel125@gmail.com> +Markus Westerlind <marwes91@gmail.com> Markus <marwes91@gmail.com> Matej Lach <matej.lach@gmail.com> Matej Ľach <matej.lach@gmail.com> Matt Brubeck <mbrubeck@limpet.net> <mbrubeck@cs.hmc.edu> Matthew Auld <matthew.auld@intel.com> Matthew McPherrin <matthew@mcpherrin.ca> <matt@mcpherrin.ca> Matthijs Hofstra <thiezz@gmail.com> Michael Williams <m.t.williams@live.com> -Michael Woerister <michaelwoerister@gmail> <michaelwoerister@gmail.com> <michaelwoerister@posteo> Michael Woerister <michaelwoerister@posteo> +Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail> +Mickaël Raybaud-Roig <raybaudroigm@gmail.com> m-r-r <raybaudroigm@gmail.com> Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com> +Mukilan Thiagarajan <mukilanthiagarajan@gmail.com> +NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> +Nathan Wilson <wilnathan@gmail.com> +Nathaniel Herman <nherman@post.harvard.edu> Nathaniel Herman <nherman@college.harvard.edu> Neil Pankey <npankey@gmail.com> <neil@wire.im> Nicholas Mazzuca <npmazzuca@gmail.com> Nicholas <npmazzuca@gmail.com> -Oliver Schneider <github6541940@oli-obk.de> <git1984941651981@oli-obk.de> <git1984941651981@oli-obk.de> Oliver 'ker' Schneider <rust19446194516@oli-obk.de> -Oliver Schneider <github6541940@oli-obk.de> Oliver Schneider <git1984941651981@oli-obk.de> Oliver Schneider <git-spam9815368754983@oli-obk.de> Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> +Nick Platt <platt.nicholas@gmail.com> +Nif Ward <nif.ward@gmail.com> +Oliver Schneider <oliver.schneider@kit.edu> oli-obk <github6541940@oli-obk.de> +Oliver Schneider <oliver.schneider@kit.edu> Oliver 'ker' Schneider <rust19446194516@oli-obk.de> +Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> +Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <git-spam9815368754983@oli-obk.de> +Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <github333195615777966@oli-obk.de> +Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <github6541940@oli-obk.de> Ožbolt Menegatti <ozbolt.menegatti@gmail.com> gareins <ozbolt.menegatti@gmail.com> Paul Faria <paul_faria@ultimatesoftware.com> Paul Faria <Nashenas88@gmail.com> Peer Aramillo Irizar <peer.aramillo.irizar@gmail.com> parir <peer.aramillo.irizar@gmail.com> Peter Elmers <peter.elmers@yahoo.com> <peter.elmers@rice.edu> +Peter Zotov <whitequark@whitequark.org> +Phil Dawes <phil@phildawes.net> Phil Dawes <pdawes@drw.com> Philipp Brüschweiler <blei42@gmail.com> <blei42@gmail.com> Philipp Brüschweiler <blei42@gmail.com> <bruphili@student.ethz.ch> -Pradeep Kumar <gohanpra@gmail.com> Przemysław Wesołek <jest@go.art.pl> Przemek Wesołek <jest@go.art.pl> +Rafael Ávila de Espíndola <respindola@mozilla.com> Rafael Avila de Espindola <espindola@dream.(none)> Ralph Giles <giles@thaumas.net> Ralph Giles <giles@mozilla.com> +Renato Riccieri Santos Zannon <renato@rrsz.com.br> Richard Diamond <wichard@vitalitystudios.com> <wichard@hahbee.co> Rob Arnold <robarnold@cs.cmu.edu> +Rob Arnold <robarnold@cs.cmu.edu> Rob Arnold <robarnold@68-26-94-7.pools.spcsdns.net> Robert Foss <dev@robertfoss.se> robertfoss <dev@robertfoss.se> Robert Gawdzik <rgawdzik@hotmail.com> Robert Gawdzik ☢ <rgawdzik@hotmail.com> Robert Millar <robert.millar@cantab.net> +Rohit Joshi <rohitjoshi@users.noreply.github.com> Rohit Joshi <rohit.joshi@capitalone.com> +Russell Johnston <rpjohnst@gmail.com> Ruud van Asseldonk <dev@veniogames.com> Ruud van Asseldonk <ruuda@google.com> Ryan Scheel <ryan.havvy@gmail.com> +S Pradeep Kumar <gohanpra@gmail.com> +Scott Olson <scott@solson.me> Scott Olson <scott@scott-olson.org> Sean Gillespie <sean.william.g@gmail.com> swgillespie <sean.william.g@gmail.com> Seonghyun Kim <sh8281.kim@samsung.com> Simon Barber-Dueck <sbarberdueck@gmail.com> Simon BD <simon@server> Simon Sapin <simon@exyr.org> <simon.sapin@exyr.org> +Simonas Kazlauskas <git@kazlauskas.me> Simonas Kazlauskas <github@kazlauskas.me> startling <tdixon51793@gmail.com> +Stepan Koltsov <stepan.koltsov@gmail.com> Stepan Koltsov <nga@yandex-team.ru> Steven Fackler <sfackler@gmail.com> <sfackler@palantir.com> Steven Stewart-Gallus <sstewartgallus00@langara.bc.ca> <sstewartgallus00@mylangara.bc.ca> +Stuart Pernsteiner <stuart@pernsteiner.org> Stuart Pernsteiner <spernsteiner@mozilla.com> Tamir Duberstein <tamird@gmail.com> Tamir Duberstein <tamird@squareup.com> +Tero Hänninen <lgvz@users.noreply.github.com> Tero Hänninen <tejohann@kapsi.fi> +Theo Belaire <theo.belaire@gmail.com> Theo Belaire <tyr.god.of.war.42@gmail.com> Thiago Pontes <email@thiago.me> thiagopnts <thiagopnts@gmail.com> +Thomas Bracht Laumann Jespersen <laumann.thomas@gmail.com> Ticki <Ticki@users.noreply.github.com> Ticki <@> +Tim Brooks <brooks@cern.ch> Tim Brooks <tim.brooks@staples.com> Tim Chevalier <chevalier@alum.wellesley.edu> <catamorphism@gmail.com> +Tim JIANG <p90eri@gmail.com> +Tim Joseph Dumol <tim@timdumol.com> Torsten Weber <TorstenWeber12@gmail.com> <torstenweber12@gmail.com> -Ulrik Sverdrup <bluss@users.noreply.github.com> Ulrik Sverdrup <root@localhost> +Ty Overby <ty@pre-alpha.com> +Ulrik Sverdrup <bluss@users.noreply.github.com> bluss <bluss> Ulrik Sverdrup <bluss@users.noreply.github.com> bluss <bluss@users.noreply.github.com> bluss <bluss> +Ulrik Sverdrup <bluss@users.noreply.github.com> Ulrik Sverdrup <root@localhost> +Vadim Petrochenkov <vadim.petrochenkov@gmail.com> Vadim Petrochenkov <vadim.petrochenkov@gmail.com> petrochenkov <vadim.petrochenkov@gmail.com> Vitali Haravy <HumaneProgrammer@gmail.com> Vitali Haravy <humaneprogrammer@gmail.com> William Ting <io@williamting.com> <william.h.ting@gmail.com> -Xuefeng Wu <benewu@gmail.com> Xuefeng Wu <xfwu@thoughtworks.com> XuefengWu <benewu@gmail.com> +Xuefeng Wu <benewu@gmail.com> Xuefeng Wu <xfwu@thoughtworks.com> +Xuefeng Wu <benewu@gmail.com> XuefengWu <benewu@gmail.com> +York Xiang <bombless@126.com> Youngsoo Son <ysson83@gmail.com> <ysoo.son@samsung.com> +Zach Pomerantz <zmp@umich.edu> Zack Corr <zack@z0w0.me> <zackcorr95@gmail.com> Zack Slayton <zack.slayton@gmail.com> +Zbigniew Siciarz <zbigniew@siciarz.net> Zbigniew Siciarz <antyqjon@gmail.com> diff --git a/AUTHORS.txt b/AUTHORS.txt index 5f316744021..b7fa4a5a4a7 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -98,7 +98,6 @@ Anton Löfgren <anton.lofgren@gmail.com> Antti Keränen <detegr@gmail.com> Aram Visser <aramvisser@gmail.com> arcnmx <arcnmx@users.noreply.github.com> -Arcterus <Arcterus@mail.com> Areski Belaid <areski@gmail.com> Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> Arjan Topolovec <arjan.top@gmail.com> @@ -136,7 +135,6 @@ Ben Gesoff <ben.gesoff@gmail.com> Ben Harris <mail@bharr.is> Ben Kelly <ben@wanderview.com> Ben Noordhuis <info@bnoordhuis.nl> -Ben S <ogham@users.noreply.github.com> Ben Sago <ogham@users.noreply.github.com> Ben Striegel <ben.striegel@gmail.com> benaryorg <binary@benary.org> @@ -434,7 +432,6 @@ Gábor Horváth <xazax.hun@gmail.com> Gábor Lehel <glaebhoerl@gmail.com> Gabriel <g2p.code@gmail.com> gamazeps <gamaz3ps@gmail.com> -gareth <gareth@gareth-N56VM.(none)> Gareth Daniel Smith <garethdanielsmith@gmail.com> Garming Sam <garming_sam@outlook.com> Garrett Heel <garrettheel@gmail.com> @@ -495,7 +492,6 @@ Igor Strebezhev <xamgore@ya.ru> Ilya Dmitrichenko <ilya@xively.com> Ilyong Cho <ilyoan@gmail.com> Ingo Blechschmidt <iblech@web.de> -inrustwetrust <inrustwetrust@users.noreply.github.com> Irving A.J. Rivas Z. <axel.rivas@gmail.com> Isaac Aggrey <isaac.aggrey@gmail.com> Isaac Dupree <antispam@idupree.com> @@ -733,7 +729,6 @@ Liam Monahan <liam@monahan.io> Liigo Zhuang <com.liigo@gmail.com> Lindsey Kuper <lindsey@composition.al> Lionel Flandrin <lionel.flandrin@parrot.com> -llogiq <bogusandre@gmail.com> Logan Chien <tzuhsiang.chien@gmail.com> Loïc Damien <loic.damien@dzamlo.ch> Lorenz <lorenzb@student.ethz.ch> @@ -760,7 +755,7 @@ Manuel Hoffmann <manuel@polythematik.de> Marc-Antoine Perennou <Marc-Antoine@Perennou.com> Marcel Müller <neikos@neikos.email> Marcel Rodrigues <marcelgmr@gmail.com> -marcell <marcell.pardavi@gmail.com> +Marcell Pardavi <marcell.pardavi@gmail.com> Marcello Seri <marcello.seri@gmail.com> Marcus Klaas <mail@marcusklaas.nl> Margaret Meyerhofer <mmeyerho@andrew.cmu.edu> @@ -924,9 +919,7 @@ Oak <White-Oak@users.noreply.github.com> OGINO Masanori <masanori.ogino@gmail.com> OlegTsyba <idethrone1@gmail.com> Oliver Schneider <git1984941651981@oli-obk.de> -Oliver Schneider <github6541940@oli-obk.de> -Oliver Schneider <git-spam9815368754983@oli-obk.de> -Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> +Oliver Schneider <oliver.schneider@kit.edu> Olivier Saut <osaut@airpost.net> olivren <o.renaud@gmx.fr> Olle Jonsson <olle.jonsson@gmail.com> @@ -937,7 +930,6 @@ Oren Hazi <oren.hazi@gmail.com> Orphée Lafond-Lummis <o@orftz.com> Orpheus Lummis <o@orpheuslummis.com> osa1 <omeragacan@gmail.com> -Overmind JIANG <p90eri@gmail.com> Ožbolt Menegatti <ozbolt.menegatti@gmail.com> P1start <rewi-github@whanau.org> Pablo Brasero <pablo@pablobm.com> @@ -978,7 +970,6 @@ Peter Schuller <peter.schuller@infidyne.com> Peter Williams <peter@newton.cx> Peter Zotov <whitequark@whitequark.org> Petter Remen <petter.remen@gmail.com> -pez <james.austin.perry@gmail.com> Phil Dawes <phil@phildawes.net> Phil Ruffwind <rf@rufflewind.com> Philip Munksgaard <pmunksgaard@gmail.com> @@ -1065,7 +1056,6 @@ Ryan Pendleton <me@ryanp.me> Ryan Prichard <ryan.prichard@gmail.com> Ryan Riginding <marc.riginding@gmail.com> Ryan Scheel <ryan.havvy@gmail.com> -Ryman <haqkrs@gmail.com> Ryo Munakata <afpacket@gmail.com> S Pradeep Kumar <gohanpra@gmail.com> Sae-bom Kim <sae-bom.kim@samsung.com> @@ -1153,7 +1143,6 @@ Swaroop C H <swaroop@swaroopch.com> Sylvestre Ledru <sylvestre@debian.org> Taliesin Beynon <taliesinb@wolfram.com> Tamir Duberstein <tamird@gmail.com> -Tamir Duberstein <tamird@squareup.com> Taras Shpot <mrshpot@gmail.com> tav <tav@espians.com> Taylor Hutchison <seanthutchison@gmail.com> @@ -1169,7 +1158,6 @@ Thiago Pontes <email@thiago.me> Thomas Backman <serenity@exscape.org> Thomas Bracht Laumann Jespersen <laumann.thomas@gmail.com> Thomas Daede <daede003@umn.edu> -Thomas Jespersen <laumann.thomas@gmail.com> Thomas Karpiniec <tk@1.21jiggawatts.net> Tiago Nobrega <tigarmo@gmail.com> Tibor Benke <ihrwein@gmail.com> @@ -1255,7 +1243,6 @@ Wei-Ming Yang <rick68@users.noreply.github.com> Wendell Smith <wendell.smith@yale.edu> Wesley Wiser <wwiser@gmail.com> whataloadofwhat <unusualmoniker@gmail.com> -whitequark <whitequark@whitequark.org> wickerwaka <martin.donlon@gmail.com> Wilfred Hughes <me@wilfred.me.uk> Will <will@glozer.net> @@ -1275,8 +1262,6 @@ Xavier Shay <xavier@rhnh.net> Xiao Chuan Yu <xcyu.se@gmail.com> Xue Fuqiao <xfq.free@gmail.com> Xuefeng Wu <benewu@gmail.com> -Xuefeng Wu <xfwu@thoughtworks.com> -XuefengWu <benewu@gmail.com> Yasuhiro Fujii <y-fujii@mimosa-pudica.net> YawarRaza7349 <YawarRaza7349@gmail.com> Yazhong Liu <yorkiefixer@gmail.com> diff --git a/mk/docs.mk b/mk/docs.mk index 644fbde323c..b0872c88c14 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -22,14 +22,14 @@ # L10N_LANGS are the languages for which the docs have been # translated. ###################################################################### -DOCS := index intro tutorial \ +DOCS := index \ complement-lang-faq complement-design-faq complement-project-faq \ rustdoc reference grammar # Legacy guides, preserved for a while to reduce the number of 404s DOCS += guide-crates guide-error-handling guide-ffi guide-macros guide \ guide-ownership guide-plugins guide-pointers guide-strings guide-tasks \ - guide-testing + guide-testing tutorial intro RUSTDOC_DEPS_reference := doc/full-toc.inc diff --git a/mk/main.mk b/mk/main.mk index a5a4869ae9a..1be09ca7257 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -380,7 +380,7 @@ HBIN$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/bin ifeq ($$(CFG_WINDOWSY_$(3)),1) # On Windows we always store host runtime libraries in the 'bin' directory because # there's no rpath. Target libraries go under $CFG_LIBDIR_RELATIVE (usually 'lib'). -HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/bin +HLIB_RELATIVE$(1)_H_$(3) = bin TROOT$(1)_T_$(2)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(CFG_LIBDIR_RELATIVE)/rustlib/$(2) # Remove the next 3 lines after a snapshot ifeq ($(1),0) @@ -390,13 +390,14 @@ endif else ifeq ($(1),0) -HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/lib +HLIB_RELATIVE$(1)_H_$(3) = lib else -HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(CFG_LIBDIR_RELATIVE) +HLIB_RELATIVE$(1)_H_$(3) = $$(CFG_LIBDIR_RELATIVE) endif TROOT$(1)_T_$(2)_H_$(3) = $$(HLIB$(1)_H_$(3))/rustlib/$(2) endif +HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(HLIB_RELATIVE$(1)_H_$(3)) # Destinations of artifacts for target architectures TBIN$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/bin diff --git a/mk/platform.mk b/mk/platform.mk index b8058882f9d..9d27f6b2a67 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -214,9 +214,11 @@ define CFG_MAKE_TOOLCHAIN # On OpenBSD, we need to pass the path of libstdc++.so to the linker # (use path of libstdc++.a which is a known name for the same path) ifeq ($(OSTYPE_$(1)),unknown-openbsd) - RUSTC_FLAGS_$(1)=-L "$$(dir $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \ - -print-file-name=lib$(CFG_STDCPP_NAME).a))" \ - $(RUSTC_FLAGS_$(1)) + STDCPP_LIBDIR_RUSTFLAGS_$(1)= \ + -L "$$(dir $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \ + -print-file-name=lib$(CFG_STDCPP_NAME).a))" + else + STDCPP_LIBDIR_RUSTFLAGS_$(1)= endif # On Bitrig, we need the relocation model to be PIC for everything diff --git a/mk/prepare.mk b/mk/prepare.mk index 8320eea8cf9..5a16afdf23a 100644 --- a/mk/prepare.mk +++ b/mk/prepare.mk @@ -115,7 +115,7 @@ define DEF_PREPARE_HOST_LIB prepare-host-lib-$(1)-$(2)-$(3)-$(4): \ PREPARE_WORKING_SOURCE_LIB_DIR=$$(HLIB$(2)_H_$(3)) prepare-host-lib-$(1)-$(2)-$(3)-$(4): \ - PREPARE_WORKING_DEST_LIB_DIR=$$(PREPARE_DEST_DIR)/$$(notdir $$(HLIB$(2)_H_$(3))) + PREPARE_WORKING_DEST_LIB_DIR=$$(PREPARE_DEST_DIR)/$$(HLIB_RELATIVE$(2)_H_$(3)) prepare-host-lib-$(1)-$(2)-$(3)-$(4): prepare-maybe-clean-$(4) \ $$(foreach dep,$$(RUST_DEPS_$(1)),prepare-host-lib-$$(dep)-$(2)-$(3)-$(4)) \ $$(HLIB$(2)_H_$(3))/stamp.$(1) \ diff --git a/mk/target.mk b/mk/target.mk index ae9fd9d1ada..a88f0a33c07 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -95,6 +95,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \ $$(RUSTFLAGS_$(4)) \ $$(RUSTFLAGS$(1)_$(4)) \ $$(RUSTFLAGS$(1)_$(4)_T_$(2)) \ + $$(STDCPP_LIBDIR_RUSTFLAGS_$(2)) \ --out-dir $$(@D) \ -C extra-filename=-$$(CFG_FILENAME_EXTRA) \ $$< @@ -128,7 +129,9 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ | $$(TBIN$(1)_T_$(2)_H_$(3))/ @$$(call E, rustc: $$@) - $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --cfg $(4) + $$(STAGE$(1)_T_$(2)_H_$(3)) \ + $$(STDCPP_LIBDIR_RUSTFLAGS_$(2)) \ + -o $$@ $$< --cfg $(4) endef diff --git a/mk/tests.mk b/mk/tests.mk index 73aec5de8da..3a0aee77d68 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -393,7 +393,8 @@ $(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): \ $$(subst @,,$$(STAGE$(1)_T_$(2)_H_$(3))) -o $$@ $$< --test \ -L "$$(RT_OUTPUT_DIR_$(2))" \ $$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \ - $$(RUSTFLAGS_$(4)) + $$(RUSTFLAGS_$(4)) \ + $$(STDCPP_LIBDIR_RUSTFLAGS_$(2)) endef @@ -663,9 +664,9 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) := \ --android-cross-path=$(CFG_ANDROID_CROSS_PATH) \ --adb-path=$(CFG_ADB) \ --adb-test-dir=$(CFG_ADB_TEST_DIR) \ - --host-rustcflags "$(RUSTC_FLAGS_$(3)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(3))" \ + --host-rustcflags "$(RUSTC_FLAGS_$(3)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(3)) $$(STDCPP_LIBDIR_RUSTFLAGS_$(3))" \ --lldb-python-dir=$(CFG_LLDB_PYTHON_DIR) \ - --target-rustcflags "$(RUSTC_FLAGS_$(2)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(2))" \ + --target-rustcflags "$(RUSTC_FLAGS_$(2)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(2)) $$(STDCPP_LIBDIR_RUSTFLAGS_$(2))" \ $$(CTEST_TESTARGS) ifdef CFG_VALGRIND_RPASS diff --git a/src/doc/index.md b/src/doc/index.md index 992b6eef5e8..5f2ef610729 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -14,9 +14,8 @@ concepts. Upon completing the book, you'll be an intermediate Rust developer, and will have a good grasp of the fundamental ideas behind Rust. -[Rust By Example][rbe] was originally a community resource, but was then -donated to the Rust project. As the name implies, it teaches you Rust through a -series of small examples. +[Rust By Example][rbe] teaches you Rust through a series of small +examples. [rbe]: http://rustbyexample.com/ @@ -32,49 +31,21 @@ library](std/index.html). There's a list of crates on the left with more specific sections, or you can use the search bar at the top to search for something if you know its name. +# The Rustonomicon + +[The Rustonomicon] is an entire book dedicated to explaining +how to write `unsafe` Rust code. It is for advanced Rust programmers. + +[The Rustonomicon]: nomicon/index.html + # Tools -[Cargo](https://crates.io) is the Rust's package manager providing access to libraries +[Cargo](http://doc.crates.io/index.html) is the Rust package manager providing access to libraries beyond the standard one, and its website contains lots of good documentation. [`rustdoc`](book/documentation.html) is the Rust's documentation generator, a tool converting annotated source code into HTML docs. -A bunch of non-official tools are available, such as [Racer](https://github.com/phildawes/racer) -(code completion engine), or [rustfmt](https://github.com/nrc/rustfmt) (source code formatter), -or text editor plugins. - -# Community & Getting Help - -If you need help with something, or just want to talk about Rust with others, -there are a few places you can do that: - -The Rust IRC channels on [irc.mozilla.org](irc://irc.mozilla.org/) are the -fastest way to get help. -[`#rust`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust) is -the general discussion channel, and you'll find people willing to help you with -any questions you may have. - -There are also three specialty channels: -[`#rust-gamedev`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-gamedev) -and -[`#rust-osdev`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-osdev) -are for game development and operating system development, respectively. -There's also -[`#rust-internals`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals), which is for discussion of the development of Rust itself. - -You can also get help on [Stack -Overflow](https://stackoverflow.com/questions/tagged/rust). Searching for your -problem might reveal someone who has asked it before! - -There is an active [subreddit](https://reddit.com/r/rust) with lots of -discussion and news about Rust. - -There is also a [user forum](https://users.rust-lang.org), for all -user-oriented discussion, and a [developer -forum](https://internals.rust-lang.org/), where the development of Rust -itself is discussed. - # FAQs There are questions that are asked quite often, so we've made FAQs for them: diff --git a/src/doc/nomicon/other-reprs.md b/src/doc/nomicon/other-reprs.md index e361fbb7ae8..2639c1d4d6f 100644 --- a/src/doc/nomicon/other-reprs.md +++ b/src/doc/nomicon/other-reprs.md @@ -26,6 +26,9 @@ still consumes a byte of space. * DSTs, tuples, and tagged unions are not a concept in C and as such are never FFI safe. +* Tuple structs are like structs with regards to `repr(C)`, as the only + difference from a struct is that the fields aren’t named. + * **If the type would have any [drop flags], they will still be added** * This is equivalent to one of `repr(u*)` (see the next section) for enums. The diff --git a/src/doc/reference.md b/src/doc/reference.md index 2ada86115b6..de9352a4275 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -99,13 +99,12 @@ Comments in Rust code follow the general C++ style of line (`//`) and block (`/* ... */`) comment forms. Nested block comments are supported. Line comments beginning with exactly _three_ slashes (`///`), and block -comments beginning with exactly one repeated asterisk in the block-open -sequence (`/**`), are interpreted as a special syntax for `doc` +comments (`/** ... */`), are interpreted as a special syntax for `doc` [attributes](#attributes). That is, they are equivalent to writing `#[doc="..."]` around the body of the comment, i.e., `/// Foo` turns into `#[doc="Foo"]`. -Line comments beginning with `//!` and block comments beginning with `/*!` are +Line comments beginning with `//!` and block comments `/*! ... !*/` are doc comments that apply to the parent of the comment, rather than the item that follows. That is, they are equivalent to writing `#![doc="..."]` around the body of the comment. `//!` comments are usually used to document diff --git a/src/doc/trpl/references-and-borrowing.md b/src/doc/trpl/references-and-borrowing.md index 944417d1096..d8758e0c695 100644 --- a/src/doc/trpl/references-and-borrowing.md +++ b/src/doc/trpl/references-and-borrowing.md @@ -171,9 +171,9 @@ to the definition of a data race: > operations are not synchronized. With references, you may have as many as you’d like, since none of them are -writing. If you are writing, you need two or more pointers to the same memory, -and you can only have one `&mut` at a time. This is how Rust prevents data -races at compile time: we’ll get errors if we break the rules. +writing. However, as we can only have one `&mut` at a time, it is impossible to +have a data race. This is how Rust prevents data races at compile time: we’ll +get errors if we break the rules. With this in mind, let’s consider our example again. @@ -378,3 +378,4 @@ statement 1 at 3:14 In the above example, `y` is declared before `x`, meaning that `y` lives longer than `x`, which is not allowed. + diff --git a/src/doc/trpl/strings.md b/src/doc/trpl/strings.md index f61b4d8ed8d..42a0acd21a2 100644 --- a/src/doc/trpl/strings.md +++ b/src/doc/trpl/strings.md @@ -12,17 +12,18 @@ encoding of UTF-8 sequences. Additionally, unlike some systems languages, strings are not null-terminated and can contain null bytes. Rust has two main types of strings: `&str` and `String`. Let’s talk about -`&str` first. These are called ‘string slices’. String literals are of the type -`&'static str`: +`&str` first. These are called ‘string slices’. A string slice has a fixed +size, and cannot be mutated. It is a reference to a sequence of UTF-8 bytes. ```rust let greeting = "Hello there."; // greeting: &'static str ``` -This string is statically allocated, meaning that it’s saved inside our -compiled program, and exists for the entire duration it runs. The `greeting` -binding is a reference to this statically allocated string. String slices -have a fixed size, and cannot be mutated. +`"Hello there."` is a string literal and its type is `&'static str`. A string +literal is a string slice that is statically allocated, meaning that it’s saved +inside our compiled program, and exists for the entire duration it runs. The +`greeting` binding is a reference to this statically allocated string. Any +function expecting a string slice will also accept a string literal. String literals can span multiple lines. There are two forms. The first will include the newline and the leading spaces: @@ -34,7 +35,7 @@ let s = "foo assert_eq!("foo\n bar", s); ``` -The second, with a `\`, does not trim the spaces: +The second, with a `\`, trims the spaces and the newline: ```rust let s = "foo\ diff --git a/src/doc/trpl/the-stack-and-the-heap.md b/src/doc/trpl/the-stack-and-the-heap.md index f835322ee71..0c78f876aa0 100644 --- a/src/doc/trpl/the-stack-and-the-heap.md +++ b/src/doc/trpl/the-stack-and-the-heap.md @@ -7,6 +7,14 @@ and a heap. If you’re familiar with how C-like languages use stack allocation, this chapter will be a refresher. If you’re not, you’ll learn about this more general concept, but with a Rust-y focus. +As with most things, when learning about them, we’ll use a simplified model to +start. This lets you get a handle on the basics, without getting bogged down +with details which are, for now, irrelevant. The examples we’ll use aren’t 100% +accurate, but are representative for the level we’re trying to learn at right +now. Once you have the basics down, learning more about how allocators are +implemented, virtual memory, and other advanced topics will reveal the leaks in +this particular abstraction. + # Memory management These two terms are about memory management. The stack and the heap are diff --git a/src/etc/add-authors.sh b/src/etc/add-authors.sh index 3ae0ec73957..e45b803fa07 100644..100755 --- a/src/etc/add-authors.sh +++ b/src/etc/add-authors.sh @@ -30,8 +30,8 @@ range="$1" authors_file="./AUTHORS.txt" tmp_file="./AUTHORS.txt.tmp" old_authors="$(cat "$authors_file" | tail -n +2 | sed "/^$/d" | sort)" -new_authors="$(git log "$range" --format="%aN <%aE>" | sort | uniq)" +new_authors="$(git log "$range" --use-mailmap --format="%aN <%aE>" | sort | uniq)" printf "%s\n\n" "Rust was written by these fine people:" > "$tmp_file" -printf "%s\n%s" "$old_authors" "$new_authors" | sort | uniq >> "$tmp_file" +printf "%s\n%s" "$old_authors" "$new_authors" | sort -fs | uniq >> "$tmp_file" mv -f "$tmp_file" "$authors_file" diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 34c8b5d4139..8205e13205f 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -87,6 +87,7 @@ use core::ptr::{self, Shared}; use core::marker::Unsize; use core::hash::{Hash, Hasher}; use core::{usize, isize}; +use core::convert::From; use heap::deallocate; const MAX_REFCOUNT: usize = (isize::MAX) as usize; @@ -896,6 +897,13 @@ impl<T: ?Sized + Hash> Hash for Arc<T> { } } +#[stable(feature = "from_for_ptrs", since = "1.6.0")] +impl<T> From<T> for Arc<T> { + fn from(t: T) -> Self { + Arc::new(t) + } +} + #[cfg(test)] mod tests { use std::clone::Clone; @@ -910,6 +918,7 @@ mod tests { use std::vec::Vec; use super::{Arc, Weak}; use std::sync::Mutex; + use std::convert::From; struct Canary(*mut atomic::AtomicUsize); @@ -1139,6 +1148,13 @@ mod tests { drop(x); assert!(y.upgrade().is_none()); } + + #[test] + fn test_from_owned() { + let foo = 123; + let foo_arc = Arc::from(foo); + assert!(123 == *foo_arc); + } } impl<T: ?Sized> borrow::Borrow<T> for Arc<T> { diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 2e4ac13b34d..b5c6cdff119 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -67,6 +67,7 @@ use core::ops::{CoerceUnsized, Deref, DerefMut}; use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace}; use core::ptr::{self, Unique}; use core::raw::TraitObject; +use core::convert::From; /// A value that represents the heap. This is the default place that the `box` /// keyword allocates into when no place is supplied. @@ -373,6 +374,13 @@ impl<T: ?Sized + Hash> Hash for Box<T> { } } +#[stable(feature = "from_for_ptrs", since = "1.6.0")] +impl<T> From<T> for Box<T> { + fn from(t: T) -> Self { + Box::new(t) + } +} + impl Box<Any> { #[inline] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index b94e74ada9c..88db3cfe4b6 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -169,6 +169,7 @@ use core::ops::Deref; #[cfg(not(stage0))] use core::ops::CoerceUnsized; use core::ptr::{self, Shared}; +use core::convert::From; use heap::deallocate; @@ -701,6 +702,13 @@ impl<T> fmt::Pointer for Rc<T> { } } +#[stable(feature = "from_for_ptrs", since = "1.6.0")] +impl<T> From<T> for Rc<T> { + fn from(t: T) -> Self { + Rc::new(t) + } +} + /// A weak version of `Rc<T>`. /// /// Weak references do not count when determining if the inner value should be @@ -906,6 +914,7 @@ mod tests { use std::result::Result::{Err, Ok}; use std::mem::drop; use std::clone::Clone; + use std::convert::From; #[test] fn test_clone() { @@ -1108,6 +1117,13 @@ mod tests { let foo: Rc<[i32]> = Rc::new([1, 2, 3]); assert_eq!(foo, foo.clone()); } + + #[test] + fn test_from_owned() { + let foo = 123; + let foo_rc = Rc::from(foo); + assert!(123 == *foo_rc); + } } impl<T: ?Sized> borrow::Borrow<T> for Rc<T> { diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 39925ddff84..178d7a4a052 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -319,8 +319,9 @@ impl<K: Ord, V> BTreeMap<K, V> { /// /// If the map did not have this key present, `None` is returned. /// - /// If the map did have this key present, that value is returned, and the - /// entry is not updated. See the [module-level documentation] for more. + /// If the map did have this key present, the key is not updated, the + /// value is updated and the old value is returned. + /// See the [module-level documentation] for more. /// /// [module-level documentation]: index.html#insert-and-complex-keys /// diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 3afc89c9841..c0f65fea7db 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -124,15 +124,15 @@ macro_rules! int_impl { /// Returns the smallest value that can be represented by this integer type. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn min_value() -> Self { + pub const fn min_value() -> Self { (-1 as Self) << ($BITS - 1) } /// Returns the largest value that can be represented by this integer type. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn max_value() -> Self { - let min = Self::min_value(); !min + pub const fn max_value() -> Self { + !Self::min_value() } /// Converts a string slice in a given base to an integer. @@ -891,12 +891,12 @@ macro_rules! uint_impl { /// Returns the smallest value that can be represented by this integer type. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn min_value() -> Self { 0 } + pub const fn min_value() -> Self { 0 } /// Returns the largest value that can be represented by this integer type. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn max_value() -> Self { !0 } + pub const fn max_value() -> Self { !0 } /// Converts a string slice in a given base to an integer. /// diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 8e2c2e6a0bf..1cd196895e3 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1500,7 +1500,7 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, &[], CRATE_NODE_ID, [].iter().cloned().chain(LinkedPath::empty()), - syntax::parse::token::special_idents::invalid.name, + syntax::parse::token::intern(&ecx.link_meta.crate_name), hir::Public); visit::walk_crate(&mut EncodeVisitor { diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index a16ef808bb6..835a96c6408 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -1444,7 +1444,6 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { hir::TyTup(tys) => { hir::TyTup(tys.into_iter().map(|ty| build_to(ty, to)).collect()) } - hir::TyParen(typ) => hir::TyParen(build_to(typ, to)), other => other }; hir::Ty { id: id, node: new_node, span: span } diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index a037621f5c0..691bac0cef8 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -44,6 +44,7 @@ pub use self::object_safety::object_safety_violations; pub use self::object_safety::ObjectSafetyViolation; pub use self::object_safety::MethodViolationCode; pub use self::object_safety::is_vtable_safe_method; +pub use self::select::EvaluationCache; pub use self::select::SelectionContext; pub use self::select::SelectionCache; pub use self::select::{MethodMatchResult, MethodMatched, MethodAmbiguous, MethodDidNotMatch}; @@ -339,32 +340,53 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, ty, bound); - let mut fulfill_cx = FulfillmentContext::new(false); - - // We can use a dummy node-id here because we won't pay any mind - // to region obligations that arise (there shouldn't really be any - // anyhow). let cause = ObligationCause::misc(span, ast::DUMMY_NODE_ID); - - fulfill_cx.register_builtin_bound(infcx, ty, bound, cause); - - // Note: we only assume something is `Copy` if we can - // *definitively* show that it implements `Copy`. Otherwise, - // assume it is move; linear is always ok. - match fulfill_cx.select_all_or_error(infcx) { - Ok(()) => { - debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} success", - ty, - bound); - true - } - Err(e) => { - debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} errors={:?}", - ty, - bound, - e); - false + let obligation = + util::predicate_for_builtin_bound(infcx.tcx, cause, bound, 0, ty); + let obligation = match obligation { + Ok(o) => o, + Err(..) => return false + }; + let result = SelectionContext::new(infcx) + .evaluate_obligation_conservatively(&obligation); + debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} => {:?}", + ty, bound, result); + + if result && (ty.has_infer_types() || ty.has_closure_types()) { + // Because of inference "guessing", selection can sometimes claim + // to succeed while the success requires a guess. To ensure + // this function's result remains infallible, we must confirm + // that guess. While imperfect, I believe this is sound. + + let mut fulfill_cx = FulfillmentContext::new(false); + + // We can use a dummy node-id here because we won't pay any mind + // to region obligations that arise (there shouldn't really be any + // anyhow). + let cause = ObligationCause::misc(span, ast::DUMMY_NODE_ID); + + fulfill_cx.register_builtin_bound(infcx, ty, bound, cause); + + // Note: we only assume something is `Copy` if we can + // *definitively* show that it implements `Copy`. Otherwise, + // assume it is move; linear is always ok. + match fulfill_cx.select_all_or_error(infcx) { + Ok(()) => { + debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} success", + ty, + bound); + true + } + Err(e) => { + debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} errors={:?}", + ty, + bound, + e); + false + } } + } else { + result } } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index f6e35cf739d..ba69632fde1 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -9,7 +9,6 @@ // except according to those terms. //! See `README.md` for high-level documentation -#![allow(dead_code)] // FIXME -- just temporarily pub use self::MethodMatchResult::*; pub use self::MethodMatchedData::*; @@ -190,7 +189,6 @@ pub enum MethodMatchedData { /// parameter environment. #[derive(PartialEq,Eq,Debug,Clone)] enum SelectionCandidate<'tcx> { - PhantomFnCandidate, BuiltinCandidate(ty::BuiltinBound), ParamCandidate(ty::PolyTraitRef<'tcx>), ImplCandidate(DefId), @@ -236,11 +234,24 @@ enum BuiltinBoundConditions<'tcx> { AmbiguousBuiltin } -#[derive(Debug)] -enum EvaluationResult<'tcx> { +#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] +/// The result of trait evaluation. The order is important +/// here as the evaluation of a list is the maximum of the +/// evaluations. +enum EvaluationResult { + /// Evaluation successful EvaluatedToOk, + /// Evaluation failed because of recursion - treated as ambiguous + EvaluatedToUnknown, + /// Evaluation is known to be ambiguous EvaluatedToAmbig, - EvaluatedToErr(SelectionError<'tcx>), + /// Evaluation failed + EvaluatedToErr, +} + +#[derive(Clone)] +pub struct EvaluationCache<'tcx> { + hashmap: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, EvaluationResult>> } impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { @@ -381,6 +392,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // The result is "true" if the obligation *may* hold and "false" if // we can be sure it does not. + /// Evaluates whether the obligation `obligation` can be satisfied (by any means). pub fn evaluate_obligation(&mut self, obligation: &PredicateObligation<'tcx>) @@ -389,45 +401,50 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("evaluate_obligation({:?})", obligation); - self.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation) - .may_apply() + self.infcx.probe(|_| { + self.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation) + .may_apply() + }) } - fn evaluate_builtin_bound_recursively<'o>(&mut self, - bound: ty::BuiltinBound, - previous_stack: &TraitObligationStack<'o, 'tcx>, - ty: Ty<'tcx>) - -> EvaluationResult<'tcx> + /// Evaluates whether the obligation `obligation` can be satisfied, + /// and returns `false` if not certain. However, this is not entirely + /// accurate if inference variables are involved. + pub fn evaluate_obligation_conservatively(&mut self, + obligation: &PredicateObligation<'tcx>) + -> bool { - let obligation = - util::predicate_for_builtin_bound( - self.tcx(), - previous_stack.obligation.cause.clone(), - bound, - previous_stack.obligation.recursion_depth + 1, - ty); - - match obligation { - Ok(obligation) => { - self.evaluate_predicate_recursively(previous_stack.list(), &obligation) - } - Err(ErrorReported) => { - EvaluatedToOk - } - } + debug!("evaluate_obligation_conservatively({:?})", + obligation); + + self.infcx.probe(|_| { + self.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation) + == EvaluatedToOk + }) } + /// Evaluates the predicates in `predicates` recursively. Note that + /// this applies projections in the predicates, and therefore + /// is run within an inference probe. fn evaluate_predicates_recursively<'a,'o,I>(&mut self, stack: TraitObligationStackList<'o, 'tcx>, predicates: I) - -> EvaluationResult<'tcx> + -> EvaluationResult where I : Iterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a { let mut result = EvaluatedToOk; for obligation in predicates { - match self.evaluate_predicate_recursively(stack, obligation) { - EvaluatedToErr(e) => { return EvaluatedToErr(e); } + let eval = self.evaluate_predicate_recursively(stack, obligation); + debug!("evaluate_predicate_recursively({:?}) = {:?}", + obligation, eval); + match eval { + EvaluatedToErr => { return EvaluatedToErr; } EvaluatedToAmbig => { result = EvaluatedToAmbig; } + EvaluatedToUnknown => { + if result < EvaluatedToUnknown { + result = EvaluatedToUnknown; + } + } EvaluatedToOk => { } } } @@ -437,7 +454,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn evaluate_predicate_recursively<'o>(&mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: &PredicateObligation<'tcx>) - -> EvaluationResult<'tcx> + -> EvaluationResult { debug!("evaluate_predicate_recursively({:?})", obligation); @@ -459,12 +476,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::Predicate::Equate(ref p) => { - let result = self.infcx.probe(|_| { - self.infcx.equality_predicate(obligation.cause.span, p) - }); - match result { + // does this code ever run? + match self.infcx.equality_predicate(obligation.cause.span, p) { Ok(()) => EvaluatedToOk, - Err(_) => EvaluatedToErr(Unimplemented), + Err(_) => EvaluatedToErr } } @@ -489,26 +504,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if object_safety::is_object_safe(self.tcx(), trait_def_id) { EvaluatedToOk } else { - EvaluatedToErr(Unimplemented) + EvaluatedToErr } } ty::Predicate::Projection(ref data) => { - self.infcx.probe(|_| { - let project_obligation = obligation.with(data.clone()); - match project::poly_project_and_unify_type(self, &project_obligation) { - Ok(Some(subobligations)) => { - self.evaluate_predicates_recursively(previous_stack, - subobligations.iter()) - } - Ok(None) => { - EvaluatedToAmbig - } - Err(_) => { - EvaluatedToErr(Unimplemented) - } + let project_obligation = obligation.with(data.clone()); + match project::poly_project_and_unify_type(self, &project_obligation) { + Ok(Some(subobligations)) => { + self.evaluate_predicates_recursively(previous_stack, + subobligations.iter()) } - }) + Ok(None) => { + EvaluatedToAmbig + } + Err(_) => { + EvaluatedToErr + } + } } } } @@ -516,22 +529,33 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn evaluate_obligation_recursively<'o>(&mut self, previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: &TraitObligation<'tcx>) - -> EvaluationResult<'tcx> + -> EvaluationResult { debug!("evaluate_obligation_recursively({:?})", obligation); let stack = self.push_stack(previous_stack, obligation); + let fresh_trait_ref = stack.fresh_trait_ref; + if let Some(result) = self.check_evaluation_cache(fresh_trait_ref) { + debug!("CACHE HIT: EVAL({:?})={:?}", + fresh_trait_ref, + result); + return result; + } let result = self.evaluate_stack(&stack); - debug!("result: {:?}", result); + debug!("CACHE MISS: EVAL({:?})={:?}", + fresh_trait_ref, + result); + self.insert_evaluation_cache(fresh_trait_ref, result); + result } fn evaluate_stack<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) - -> EvaluationResult<'tcx> + -> EvaluationResult { // In intercrate mode, whenever any of the types are unbound, // there can always be an impl. Even if there are no impls in @@ -559,16 +583,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // precise still. let input_types = stack.fresh_trait_ref.0.input_types(); let unbound_input_types = input_types.iter().any(|ty| ty.is_fresh()); - if - unbound_input_types && - (self.intercrate || + if unbound_input_types && self.intercrate { + debug!("evaluate_stack({:?}) --> unbound argument, intercrate --> ambiguous", + stack.fresh_trait_ref); + return EvaluatedToAmbig; + } + if unbound_input_types && stack.iter().skip(1).any( |prev| self.match_fresh_trait_refs(&stack.fresh_trait_ref, - &prev.fresh_trait_ref))) + &prev.fresh_trait_ref)) { - debug!("evaluate_stack({:?}) --> unbound argument, recursion --> ambiguous", + debug!("evaluate_stack({:?}) --> unbound argument, recursive --> giving up", stack.fresh_trait_ref); - return EvaluatedToAmbig; + return EvaluatedToUnknown; } // If there is any previous entry on the stack that precisely @@ -601,40 +628,74 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } match self.candidate_from_obligation(stack) { - Ok(Some(c)) => self.winnow_candidate(stack, &c), + Ok(Some(c)) => self.evaluate_candidate(stack, &c), Ok(None) => EvaluatedToAmbig, - Err(e) => EvaluatedToErr(e), + Err(..) => EvaluatedToErr } } - /// Evaluates whether the impl with id `impl_def_id` could be applied to the self type - /// `obligation_self_ty`. This can be used either for trait or inherent impls. - pub fn evaluate_impl(&mut self, - impl_def_id: DefId, - obligation: &TraitObligation<'tcx>) - -> bool + /// Further evaluate `candidate` to decide whether all type parameters match and whether nested + /// obligations are met. Returns true if `candidate` remains viable after this further + /// scrutiny. + fn evaluate_candidate<'o>(&mut self, + stack: &TraitObligationStack<'o, 'tcx>, + candidate: &SelectionCandidate<'tcx>) + -> EvaluationResult { - debug!("evaluate_impl(impl_def_id={:?}, obligation={:?})", - impl_def_id, - obligation); - - self.infcx.probe(|snapshot| { - match self.match_impl(impl_def_id, obligation, snapshot) { - Ok((substs, skol_map)) => { - let vtable_impl = self.vtable_impl(impl_def_id, - substs, - obligation.cause.clone(), - obligation.recursion_depth + 1, - skol_map, - snapshot); - self.winnow_selection(TraitObligationStackList::empty(), - VtableImpl(vtable_impl)).may_apply() - } - Err(()) => { - false + debug!("evaluate_candidate: depth={} candidate={:?}", + stack.obligation.recursion_depth, candidate); + let result = self.infcx.probe(|_| { + let candidate = (*candidate).clone(); + match self.confirm_candidate(stack.obligation, candidate) { + Ok(selection) => { + self.evaluate_predicates_recursively( + stack.list(), + selection.nested_obligations().iter()) } + Err(..) => EvaluatedToErr } - }) + }); + debug!("evaluate_candidate: depth={} result={:?}", + stack.obligation.recursion_depth, result); + result + } + + fn pick_evaluation_cache(&self) -> &EvaluationCache<'tcx> { + // see comment in `pick_candidate_cache` + if self.intercrate || + !self.param_env().caller_bounds.is_empty() + { + &self.param_env().evaluation_cache + } else + { + &self.tcx().evaluation_cache + } + } + + fn check_evaluation_cache(&self, trait_ref: ty::PolyTraitRef<'tcx>) + -> Option<EvaluationResult> + { + let cache = self.pick_evaluation_cache(); + cache.hashmap.borrow().get(&trait_ref).cloned() + } + + fn insert_evaluation_cache(&mut self, + trait_ref: ty::PolyTraitRef<'tcx>, + result: EvaluationResult) + { + // Avoid caching results that depend on more than just the trait-ref: + // The stack can create EvaluatedToUnknown, and closure signatures + // being yet uninferred can create "spurious" EvaluatedToAmbig + // and EvaluatedToOk. + if result == EvaluatedToUnknown || + ((result == EvaluatedToAmbig || result == EvaluatedToOk) + && trait_ref.has_closure_types()) + { + return; + } + + let cache = self.pick_evaluation_cache(); + cache.hashmap.borrow_mut().insert(trait_ref, result); } /////////////////////////////////////////////////////////////////////////// @@ -669,7 +730,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.check_candidate_cache(&cache_fresh_trait_pred) { Some(c) => { - debug!("CACHE HIT: cache_fresh_trait_pred={:?}, candidate={:?}", + debug!("CACHE HIT: SELECT({:?})={:?}", cache_fresh_trait_pred, c); return c; @@ -681,7 +742,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let candidate = self.candidate_from_obligation_no_cache(stack); if self.should_update_candidate_cache(&cache_fresh_trait_pred, &candidate) { - debug!("CACHE MISS: cache_fresh_trait_pred={:?}, candidate={:?}", + debug!("CACHE MISS: SELECT({:?})={:?}", cache_fresh_trait_pred, candidate); self.insert_candidate_cache(cache_fresh_trait_pred, candidate.clone()); } @@ -740,7 +801,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Instead, we select the right impl now but report `Bar does // not implement Clone`. if candidates.len() > 1 { - candidates.retain(|c| self.winnow_candidate(stack, c).may_apply()) + candidates.retain(|c| self.evaluate_candidate(stack, c).may_apply()) } // If there are STILL multiple candidate, we can further reduce @@ -1138,16 +1199,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn evaluate_where_clause<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>, where_clause_trait_ref: ty::PolyTraitRef<'tcx>) - -> EvaluationResult<'tcx> + -> EvaluationResult { self.infcx().probe(move |_| { match self.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) { Ok(obligations) => { self.evaluate_predicates_recursively(stack.list(), obligations.iter()) } - Err(()) => { - EvaluatedToErr(Unimplemented) - } + Err(()) => EvaluatedToErr } }) } @@ -1486,37 +1545,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // attempt to evaluate recursive bounds to see if they are // satisfied. - /// Further evaluate `candidate` to decide whether all type parameters match and whether nested - /// obligations are met. Returns true if `candidate` remains viable after this further - /// scrutiny. - fn winnow_candidate<'o>(&mut self, - stack: &TraitObligationStack<'o, 'tcx>, - candidate: &SelectionCandidate<'tcx>) - -> EvaluationResult<'tcx> - { - debug!("winnow_candidate: candidate={:?}", candidate); - let result = self.infcx.probe(|_| { - let candidate = (*candidate).clone(); - match self.confirm_candidate(stack.obligation, candidate) { - Ok(selection) => self.winnow_selection(stack.list(), - selection), - Err(error) => EvaluatedToErr(error), - } - }); - debug!("winnow_candidate depth={} result={:?}", - stack.obligation.recursion_depth, result); - result - } - - fn winnow_selection<'o>(&mut self, - stack: TraitObligationStackList<'o,'tcx>, - selection: Selection<'tcx>) - -> EvaluationResult<'tcx> - { - self.evaluate_predicates_recursively(stack, - selection.nested_obligations().iter()) - } - /// Returns true if `candidate_i` should be dropped in favor of /// `candidate_j`. Generally speaking we will drop duplicate /// candidates and prefer where-clause candidates. @@ -1542,9 +1570,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { "default implementations shouldn't be recorded \ when there are other valid candidates"); } - &PhantomFnCandidate => { - self.tcx().sess.bug("PhantomFn didn't short-circuit selection"); - } &ImplCandidate(..) | &ClosureCandidate(..) | &FnPointerCandidate(..) | @@ -1974,7 +1999,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { try!(self.confirm_builtin_candidate(obligation, builtin_bound)))) } - PhantomFnCandidate | ErrorCandidate => { Ok(VtableBuiltin(VtableBuiltinData { nested: vec![] })) } @@ -2260,6 +2284,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl_def_id, impl_obligations); + // Because of RFC447, the impl-trait-ref and obligations + // are sufficient to determine the impl substs, without + // relying on projections in the impl-trait-ref. + // + // e.g. `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V` impl_obligations.append(&mut substs.obligations); VtableImplData { impl_def_id: impl_def_id, @@ -2744,74 +2773,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - /// Determines whether the self type declared against - /// `impl_def_id` matches `obligation_self_ty`. If successful, - /// returns the substitutions used to make them match. See - /// `match_impl()`. For example, if `impl_def_id` is declared - /// as: - /// - /// impl<T:Copy> Foo for Box<T> { ... } - /// - /// and `obligation_self_ty` is `int`, we'd get back an `Err(_)` - /// result. But if `obligation_self_ty` were `Box<int>`, we'd get - /// back `Ok(T=int)`. - fn match_inherent_impl(&mut self, - impl_def_id: DefId, - obligation_cause: &ObligationCause, - obligation_self_ty: Ty<'tcx>) - -> Result<Substs<'tcx>,()> - { - // Create fresh type variables for each type parameter declared - // on the impl etc. - let impl_substs = util::fresh_type_vars_for_impl(self.infcx, - obligation_cause.span, - impl_def_id); - - // Find the self type for the impl. - let impl_self_ty = self.tcx().lookup_item_type(impl_def_id).ty; - let impl_self_ty = impl_self_ty.subst(self.tcx(), &impl_substs); - - debug!("match_impl_self_types(obligation_self_ty={:?}, impl_self_ty={:?})", - obligation_self_ty, - impl_self_ty); - - match self.match_self_types(obligation_cause, - impl_self_ty, - obligation_self_ty) { - Ok(()) => { - debug!("Matched impl_substs={:?}", impl_substs); - Ok(impl_substs) - } - Err(()) => { - debug!("NoMatch"); - Err(()) - } - } - } - - fn match_self_types(&mut self, - cause: &ObligationCause, - - // The self type provided by the impl/caller-obligation: - provided_self_ty: Ty<'tcx>, - - // The self type the obligation is for: - required_self_ty: Ty<'tcx>) - -> Result<(),()> - { - // FIXME(#5781) -- equating the types is stronger than - // necessary. Should consider variance of trait w/r/t Self. - - let origin = infer::RelateSelfType(cause.span); - match self.infcx.eq_types(false, - origin, - provided_self_ty, - required_self_ty) { - Ok(()) => Ok(()), - Err(_) => Err(()), - } - } - /////////////////////////////////////////////////////////////////////////// // Miscellany @@ -2892,17 +2853,37 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { -> Vec<PredicateObligation<'tcx>> { debug!("impl_or_trait_obligations(def_id={:?})", def_id); + let tcx = self.tcx(); - let predicates = self.tcx().lookup_predicates(def_id); - let predicates = predicates.instantiate(self.tcx(), substs); - let predicates = normalize_with_depth(self, cause.clone(), recursion_depth, &predicates); - let mut predicates = self.infcx().plug_leaks(skol_map, snapshot, &predicates); - let mut obligations = - util::predicates_for_generics(cause, - recursion_depth, - &predicates.value); - obligations.append(&mut predicates.obligations); - obligations + // To allow for one-pass evaluation of the nested obligation, + // each predicate must be preceded by the obligations required + // to normalize it. + // for example, if we have: + // impl<U: Iterator, V: Iterator<Item=U>> Foo for V where U::Item: Copy + // the impl will have the following predicates: + // <V as Iterator>::Item = U, + // U: Iterator, U: Sized, + // V: Iterator, V: Sized, + // <U as Iterator>::Item: Copy + // When we substitute, say, `V => IntoIter<u32>, U => $0`, the last + // obligation will normalize to `<$0 as Iterator>::Item = $1` and + // `$1: Copy`, so we must ensure the obligations are emitted in + // that order. + let predicates = tcx + .lookup_predicates(def_id) + .predicates.iter() + .flat_map(|predicate| { + let predicate = + normalize_with_depth(self, cause.clone(), recursion_depth, + &predicate.subst(tcx, substs)); + predicate.obligations.into_iter().chain( + Some(Obligation { + cause: cause.clone(), + recursion_depth: recursion_depth, + predicate: predicate.value + })) + }).collect(); + self.infcx().plug_leaks(skol_map, snapshot, &predicates) } #[allow(unused_comparisons)] @@ -2956,6 +2937,14 @@ impl<'tcx> SelectionCache<'tcx> { } } +impl<'tcx> EvaluationCache<'tcx> { + pub fn new() -> EvaluationCache<'tcx> { + EvaluationCache { + hashmap: RefCell::new(FnvHashMap()) + } + } +} + impl<'o,'tcx> TraitObligationStack<'o,'tcx> { fn list(&'o self) -> TraitObligationStackList<'o,'tcx> { TraitObligationStackList::with(self) @@ -3001,17 +2990,14 @@ impl<'o,'tcx> fmt::Debug for TraitObligationStack<'o,'tcx> { } } -impl<'tcx> EvaluationResult<'tcx> { +impl EvaluationResult { fn may_apply(&self) -> bool { match *self { EvaluatedToOk | EvaluatedToAmbig | - EvaluatedToErr(OutputTypeParameterMismatch(..)) | - EvaluatedToErr(TraitNotObjectSafe(_)) => - true, + EvaluatedToUnknown => true, - EvaluatedToErr(Unimplemented) => - false, + EvaluatedToErr => false } } } diff --git a/src/librustc/middle/ty/context.rs b/src/librustc/middle/ty/context.rs index d91cac4cc75..e02a120a5c6 100644 --- a/src/librustc/middle/ty/context.rs +++ b/src/librustc/middle/ty/context.rs @@ -332,6 +332,11 @@ pub struct ctxt<'tcx> { /// for things that do not have to do with the parameters in scope. pub selection_cache: traits::SelectionCache<'tcx>, + /// Caches the results of trait evaluation. This cache is used + /// for things that do not have to do with the parameters in scope. + /// Merge this with `selection_cache`? + pub evaluation_cache: traits::EvaluationCache<'tcx>, + /// A set of predicates that have been fulfilled *somewhere*. /// This is used to avoid duplicate work. Predicates are only /// added to this set when they mention only "global" names @@ -512,6 +517,7 @@ impl<'tcx> ctxt<'tcx> { transmute_restrictions: RefCell::new(Vec::new()), stability: RefCell::new(stability), selection_cache: traits::SelectionCache::new(), + evaluation_cache: traits::EvaluationCache::new(), repr_hint_cache: RefCell::new(DefIdMap()), const_qualif_map: RefCell::new(NodeMap()), custom_coerce_unsized_kinds: RefCell::new(DefIdMap()), diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs index aa189744701..0a9fa1d6ce3 100644 --- a/src/librustc/middle/ty/mod.rs +++ b/src/librustc/middle/ty/mod.rs @@ -1091,6 +1091,9 @@ pub struct ParameterEnvironment<'a, 'tcx:'a> { /// for things that have to do with the parameters in scope. pub selection_cache: traits::SelectionCache<'tcx>, + /// Caches the results of trait evaluation. + pub evaluation_cache: traits::EvaluationCache<'tcx>, + /// Scope that is attached to free regions for this scope. This /// is usually the id of the fn body, but for more abstract scopes /// like structs we often use the node-id of the struct. @@ -1112,6 +1115,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { implicit_region_bound: self.implicit_region_bound, caller_bounds: caller_bounds, selection_cache: traits::SelectionCache::new(), + evaluation_cache: traits::EvaluationCache::new(), free_id: self.free_id, } } @@ -2584,6 +2588,7 @@ impl<'tcx> ctxt<'tcx> { caller_bounds: Vec::new(), implicit_region_bound: ty::ReEmpty, selection_cache: traits::SelectionCache::new(), + evaluation_cache: traits::EvaluationCache::new(), // for an empty parameter // environment, there ARE no free @@ -2673,6 +2678,7 @@ impl<'tcx> ctxt<'tcx> { implicit_region_bound: ty::ReScope(free_id_outlive), caller_bounds: predicates, selection_cache: traits::SelectionCache::new(), + evaluation_cache: traits::EvaluationCache::new(), free_id: free_id, }; diff --git a/src/librustc/middle/ty/structural_impls.rs b/src/librustc/middle/ty/structural_impls.rs index 176dc5a743d..41303b46dfd 100644 --- a/src/librustc/middle/ty/structural_impls.rs +++ b/src/librustc/middle/ty/structural_impls.rs @@ -822,6 +822,7 @@ impl<'a, 'tcx> TypeFoldable<'tcx> for ty::ParameterEnvironment<'a, 'tcx> where ' implicit_region_bound: self.implicit_region_bound.fold_with(folder), caller_bounds: self.caller_bounds.fold_with(folder), selection_cache: traits::SelectionCache::new(), + evaluation_cache: traits::EvaluationCache::new(), free_id: self.free_id, } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index cf9de56c8db..90c93616232 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -44,7 +44,7 @@ pub fn gather_decl<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, pub fn gather_move_from_expr<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, move_data: &MoveData<'tcx>, - move_error_collector: &MoveErrorCollector<'tcx>, + move_error_collector: &mut MoveErrorCollector<'tcx>, move_expr_id: ast::NodeId, cmt: mc::cmt<'tcx>, move_reason: euv::MoveReason) { @@ -63,7 +63,7 @@ pub fn gather_move_from_expr<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, pub fn gather_match_variant<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, move_data: &MoveData<'tcx>, - _move_error_collector: &MoveErrorCollector<'tcx>, + _move_error_collector: &mut MoveErrorCollector<'tcx>, move_pat: &hir::Pat, cmt: mc::cmt<'tcx>, mode: euv::MatchMode) { @@ -94,7 +94,7 @@ pub fn gather_match_variant<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, move_data: &MoveData<'tcx>, - move_error_collector: &MoveErrorCollector<'tcx>, + move_error_collector: &mut MoveErrorCollector<'tcx>, move_pat: &hir::Pat, cmt: mc::cmt<'tcx>) { let pat_span_path_opt = match move_pat.node { @@ -115,7 +115,7 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, fn gather_move<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, move_data: &MoveData<'tcx>, - move_error_collector: &MoveErrorCollector<'tcx>, + move_error_collector: &mut MoveErrorCollector<'tcx>, move_info: GatherMoveInfo<'tcx>) { debug!("gather_move(move_id={}, cmt={:?})", move_info.id, move_info.cmt); diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 99e4bb60aff..de0b1fddc20 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -86,7 +86,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { match mode { euv::Move(move_reason) => { gather_moves::gather_move_from_expr( - self.bccx, &self.move_data, &self.move_error_collector, + self.bccx, &self.move_data, &mut self.move_error_collector, consume_id, cmt, move_reason); } euv::Copy => { } @@ -104,7 +104,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { if let Categorization::Downcast(..) = cmt.cat { gather_moves::gather_match_variant( - self.bccx, &self.move_data, &self.move_error_collector, + self.bccx, &self.move_data, &mut self.move_error_collector, matched_pat, cmt, mode); } } @@ -124,7 +124,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { } gather_moves::gather_move_from_pat( - self.bccx, &self.move_data, &self.move_error_collector, + self.bccx, &self.move_data, &mut self.move_error_collector, consume_pat, cmt); } diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index fb703a9f9bc..a56a03174f6 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -13,28 +13,27 @@ use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; use rustc::middle::mem_categorization::InteriorOffsetKind as Kind; use rustc::middle::ty; -use std::cell::RefCell; use syntax::ast; use syntax::codemap; use rustc_front::hir; pub struct MoveErrorCollector<'tcx> { - errors: RefCell<Vec<MoveError<'tcx>>> + errors: Vec<MoveError<'tcx>> } impl<'tcx> MoveErrorCollector<'tcx> { pub fn new() -> MoveErrorCollector<'tcx> { MoveErrorCollector { - errors: RefCell::new(Vec::new()) + errors: Vec::new() } } - pub fn add_error(&self, error: MoveError<'tcx>) { - self.errors.borrow_mut().push(error); + pub fn add_error(&mut self, error: MoveError<'tcx>) { + self.errors.push(error); } pub fn report_potential_errors<'a>(&self, bccx: &BorrowckCtxt<'a, 'tcx>) { - report_move_errors(bccx, &*self.errors.borrow()) + report_move_errors(bccx, &self.errors) } } diff --git a/src/librustc_front/fold.rs b/src/librustc_front/fold.rs index 955de44b43f..b38aae240f5 100644 --- a/src/librustc_front/fold.rs +++ b/src/librustc_front/fold.rs @@ -382,7 +382,6 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { })) } TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))), - TyParen(ty) => TyParen(fld.fold_ty(ty)), TyPath(qself, path) => { let qself = qself.map(|QSelf { ty, position }| { QSelf { diff --git a/src/librustc_front/hir.rs b/src/librustc_front/hir.rs index b017a07dde0..aa21c3ea042 100644 --- a/src/librustc_front/hir.rs +++ b/src/librustc_front/hir.rs @@ -848,8 +848,6 @@ pub enum Ty_ { TyObjectSum(P<Ty>, TyParamBounds), /// A type like `for<'a> Foo<&'a Bar>` TyPolyTraitRef(TyParamBounds), - /// No-op; kept solely so that we can pretty-print faithfully - TyParen(P<Ty>), /// Unused for now TyTypeof(P<Expr>), /// TyInfer means the type should be inferred instead of it having been diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs index d13b92c04f8..0a591919822 100644 --- a/src/librustc_front/lowering.rs +++ b/src/librustc_front/lowering.rs @@ -225,7 +225,9 @@ pub fn lower_ty(_lctx: &LoweringContext, t: &Ty) -> P<hir::Ty> { })) } TyTup(ref tys) => hir::TyTup(tys.iter().map(|ty| lower_ty(_lctx, ty)).collect()), - TyParen(ref ty) => hir::TyParen(lower_ty(_lctx, ty)), + TyParen(ref ty) => { + return lower_ty(_lctx, ty); + } TyPath(ref qself, ref path) => { let qself = qself.as_ref().map(|&QSelf { ref ty, position }| { hir::QSelf { diff --git a/src/librustc_front/print/pprust.rs b/src/librustc_front/print/pprust.rs index 2fd374f7560..002181c357b 100644 --- a/src/librustc_front/print/pprust.rs +++ b/src/librustc_front/print/pprust.rs @@ -506,11 +506,6 @@ impl<'a> State<'a> { } try!(self.pclose()); } - hir::TyParen(ref typ) => { - try!(self.popen()); - try!(self.print_type(&**typ)); - try!(self.pclose()); - } hir::TyBareFn(ref f) => { let generics = hir::Generics { lifetimes: f.lifetimes.clone(), diff --git a/src/librustc_front/visit.rs b/src/librustc_front/visit.rs index 94986ceced6..8307543958f 100644 --- a/src/librustc_front/visit.rs +++ b/src/librustc_front/visit.rs @@ -349,7 +349,7 @@ pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { match typ.node { - TyVec(ref ty) | TyParen(ref ty) => { + TyVec(ref ty) => { visitor.visit_ty(ty) } TyPtr(ref mutable_type) => { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 0bbceafa4a8..3481f1bfd52 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -66,7 +66,7 @@ enum DuplicateCheckingMode { ForbidDuplicateTypesAndModules, ForbidDuplicateValues, ForbidDuplicateTypesAndValues, - OverwriteDuplicates + OverwriteDuplicates, } #[derive(Copy, Clone, PartialEq)] @@ -74,19 +74,19 @@ enum NamespaceError { NoError, ModuleError, TypeError, - ValueError + ValueError, } fn namespace_error_to_string(ns: NamespaceError) -> &'static str { match ns { - NoError => "", + NoError => "", ModuleError | TypeError => "type or module", - ValueError => "value", + ValueError => "value", } } -struct GraphBuilder<'a, 'b:'a, 'tcx:'b> { - resolver: &'a mut Resolver<'b, 'tcx> +struct GraphBuilder<'a, 'b: 'a, 'tcx: 'b> { + resolver: &'a mut Resolver<'b, 'tcx>, } impl<'a, 'b:'a, 'tcx:'b> Deref for GraphBuilder<'a, 'b, 'tcx> { @@ -109,7 +109,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { let parent = self.graph_root.get_module(); let mut visitor = BuildReducedGraphVisitor { builder: self, - parent: parent + parent: parent, }; visit::walk_crate(&mut visitor, krate); } @@ -135,9 +135,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { // child name directly. Otherwise, we create or reuse an anonymous // module and add the child to that. - self.check_for_conflicts_between_external_crates_and_items(&**parent, - name, - sp); + self.check_for_conflicts_between_external_crates_and_items(&**parent, name, sp); // Add or reuse the child. let child = parent.children.borrow().get(&name).cloned(); @@ -194,14 +192,14 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { n = Some(TypeNS); duplicate_type = TypeError; } - }; + } if child.defined_in_namespace(ValueNS) { duplicate_type = ValueError; n = Some(ValueNS); } n } - OverwriteDuplicates => None + OverwriteDuplicates => None, }; if duplicate_type != NoError { // Return an error here by looking up the namespace that @@ -218,7 +216,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { let r = child.span_for_namespace(ns); if let Some(sp) = r { self.session.span_note(sp, - &format!("first definition of {} `{}` here", + &format!("first definition of {} `{}` here", namespace_error_to_string(duplicate_type), name)); } @@ -278,15 +276,20 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { let module_path = match view_path.node { ViewPathSimple(_, ref full_path) => { full_path.segments - .split_last().unwrap().1 - .iter().map(|seg| seg.identifier.name) - .collect() + .split_last() + .unwrap() + .1 + .iter() + .map(|seg| seg.identifier.name) + .collect() } ViewPathGlob(ref module_ident_path) | ViewPathList(ref module_ident_path, _) => { module_ident_path.segments - .iter().map(|seg| seg.identifier.name).collect() + .iter() + .map(|seg| seg.identifier.name) + .collect() } }; @@ -302,8 +305,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { match view_path.node { ViewPathSimple(binding, ref full_path) => { - let source_name = - full_path.segments.last().unwrap().identifier.name; + let source_name = full_path.segments.last().unwrap().identifier.name; if source_name.as_str() == "mod" || source_name.as_str() == "self" { resolve_error(self, view_path.span, @@ -321,19 +323,21 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { } ViewPathList(_, ref source_items) => { // Make sure there's at most one `mod` import in the list. - let mod_spans = source_items.iter().filter_map(|item| match item.node { - PathListMod { .. } => Some(item.span), - _ => None - }).collect::<Vec<Span>>(); + let mod_spans = source_items.iter() + .filter_map(|item| { + match item.node { + PathListMod { .. } => Some(item.span), + _ => None, + } + }) + .collect::<Vec<Span>>(); if mod_spans.len() > 1 { - resolve_error( - self, - mod_spans[0], - ResolutionError::SelfImportCanOnlyAppearOnceInTheList - ); + resolve_error(self, + mod_spans[0], + ResolutionError::SelfImportCanOnlyAppearOnceInTheList); for other_span in mod_spans.iter().skip(1) { - self.session.span_note(*other_span, - "another `self` import appears here"); + self.session + .span_note(*other_span, "another `self` import appears here"); } } @@ -359,14 +363,13 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { (module_path.to_vec(), name, rename) } }; - self.build_import_directive( - &**parent, - module_path, - SingleImport(rename, name), - source_item.span, - source_item.node.id(), - is_public, - shadowable); + self.build_import_directive(&**parent, + module_path, + SingleImport(rename, name), + source_item.span, + source_item.node.id(), + is_public, + shadowable); } } ViewPathGlob(_) => { @@ -383,9 +386,13 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { } ItemExternCrate(_) => { - // n.b. we don't need to look at the path option here, because cstore already did + // n.b. we don't need to look at the path option here, because cstore already + // did if let Some(crate_id) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) { - let def_id = DefId { krate: crate_id, index: CRATE_DEF_INDEX }; + let def_id = DefId { + krate: crate_id, + index: CRATE_DEF_INDEX, + }; self.external_exports.insert(def_id); let parent_link = ModuleParentLink(Rc::downgrade(parent), name); let external_module = Rc::new(Module::new(parent_link, @@ -394,9 +401,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { false, true)); debug!("(build reduced graph for item) found extern `{}`", - module_to_string(&*external_module)); + module_to_string(&*external_module)); self.check_for_conflicts_between_external_crates(&**parent, name, sp); - parent.external_module_children.borrow_mut() + parent.external_module_children + .borrow_mut() .insert(name, external_module.clone()); self.build_reduced_graph_for_external_crate(&external_module); } @@ -407,20 +415,19 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { let child = parent.children.borrow().get(&name).cloned(); if let Some(child) = child { // check if there's struct of the same name already defined - if child.defined_in_namespace(TypeNS) - && child.get_module_if_available().is_none() { - self.session.span_warn(sp, &format!( - "duplicate definition of {} `{}`. \ - Defining a module and a struct with \ - the same name will be disallowed \ - soon.", - namespace_error_to_string(TypeError), - name)); + if child.defined_in_namespace(TypeNS) && + child.get_module_if_available().is_none() { + self.session.span_warn(sp, + &format!("duplicate definition of {} `{}`. \ + Defining a module and a struct with \ + the same name will be disallowed soon.", + namespace_error_to_string(TypeError), + name)); { let r = child.span_for_namespace(TypeNS); if let Some(sp) = r { self.session.span_note(sp, - &format!("first definition of {} `{}` here", + &format!("first definition of {} `{}` here", namespace_error_to_string(TypeError), name)); } @@ -468,10 +475,13 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { // These items live in the type namespace. ItemTy(..) => { - let name_bindings = - self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp); + let name_bindings = self.add_child(name, + parent, + ForbidDuplicateTypesAndModules, + sp); - name_bindings.define_type(DefTy(self.ast_map.local_def_id(item.id), false), sp, + name_bindings.define_type(DefTy(self.ast_map.local_def_id(item.id), false), + sp, modifiers); let parent_link = self.get_parent_link(parent, name); @@ -485,8 +495,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { } ItemEnum(ref enum_definition, _) => { - let name_bindings = - self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp); + let name_bindings = self.add_child(name, + parent, + ForbidDuplicateTypesAndModules, + sp); name_bindings.define_type(DefTy(self.ast_map.local_def_id(item.id), true), sp, @@ -504,10 +516,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { for variant in &(*enum_definition).variants { let item_def_id = self.ast_map.local_def_id(item.id); - self.build_reduced_graph_for_variant( - &**variant, - item_def_id, - &module); + self.build_reduced_graph_for_variant(&**variant, item_def_id, &module); } parent.clone() } @@ -522,20 +531,21 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { if let Some(child) = child { // check if theres a DefMod if let Some(DefMod(_)) = child.def_for_namespace(TypeNS) { - self.session.span_warn(sp, &format!( - "duplicate definition of {} `{}`. \ - Defining a module and a struct with \ - the same name will be disallowed \ - soon.", - namespace_error_to_string(TypeError), - name)); + self.session.span_warn(sp, + &format!("duplicate definition of {} `{}`. \ + Defining a module and a struct \ + with the same name will be \ + disallowed soon.", + namespace_error_to_string(TypeError), + name)); { let r = child.span_for_namespace(TypeNS); if let Some(sp) = r { - self.session.span_note(sp, - &format!("first definition of {} `{}` here", - namespace_error_to_string(TypeError), - name)); + self.session + .span_note(sp, + &format!("first definition of {} `{}` here", + namespace_error_to_string(TypeError), + name)); } } } @@ -559,12 +569,15 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { } // Record the def ID and fields of this struct. - let named_fields = struct_def.fields().iter().filter_map(|f| { - match f.node.kind { - NamedField(name, _) => Some(name), - UnnamedField(_) => None - } - }).collect(); + let named_fields = struct_def.fields() + .iter() + .filter_map(|f| { + match f.node.kind { + NamedField(name, _) => Some(name), + UnnamedField(_) => None, + } + }) + .collect(); let item_def_id = self.ast_map.local_def_id(item.id); self.structs.insert(item_def_id, named_fields); @@ -575,8 +588,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { ItemImpl(..) => parent.clone(), ItemTrait(_, _, _, ref items) => { - let name_bindings = - self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp); + let name_bindings = self.add_child(name, + parent, + ForbidDuplicateTypesAndModules, + sp); // Add all the items within to a new module. let parent_link = self.get_parent_link(parent, name); @@ -593,9 +608,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { // Add the names of all the items to the trait info. for trait_item in items { let name_bindings = self.add_child(trait_item.name, - &module_parent, - ForbidDuplicateTypesAndValues, - trait_item.span); + &module_parent, + ForbidDuplicateTypesAndValues, + trait_item.span); match trait_item.node { hir::ConstTraitItem(..) => { @@ -642,19 +657,19 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { false }; - let child = self.add_child(name, parent, - ForbidDuplicateTypesAndValues, - variant.span); + let child = self.add_child(name, parent, ForbidDuplicateTypesAndValues, variant.span); // variants are always treated as importable to allow them to be glob // used child.define_value(DefVariant(item_id, self.ast_map.local_def_id(variant.node.data.id()), is_exported), - variant.span, DefModifiers::PUBLIC | DefModifiers::IMPORTABLE); + variant.span, + DefModifiers::PUBLIC | DefModifiers::IMPORTABLE); child.define_type(DefVariant(item_id, self.ast_map.local_def_id(variant.node.data.id()), is_exported), - variant.span, DefModifiers::PUBLIC | DefModifiers::IMPORTABLE); + variant.span, + DefModifiers::PUBLIC | DefModifiers::IMPORTABLE); } /// Constructs the reduced graph for one foreign item. @@ -668,9 +683,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { } else { DefModifiers::empty() } | DefModifiers::IMPORTABLE; - let name_bindings = - self.add_child(name, parent, ForbidDuplicateValues, - foreign_item.span); + let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, foreign_item.span); let def = match foreign_item.node { ForeignItemFn(..) => { @@ -687,16 +700,15 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { if self.block_needs_anonymous_module(block) { let block_id = block.id; - debug!("(building reduced graph for block) creating a new \ - anonymous module for block {}", + debug!("(building reduced graph for block) creating a new anonymous module for block \ + {}", block_id); - let new_module = Rc::new(Module::new( - BlockParentLink(Rc::downgrade(parent), block_id), - None, - AnonymousModuleKind, - false, - false)); + let new_module = Rc::new(Module::new(BlockParentLink(Rc::downgrade(parent), block_id), + None, + AnonymousModuleKind, + false, + false)); parent.anonymous_children.borrow_mut().insert(block_id, new_module.clone()); new_module } else { @@ -711,18 +723,19 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { final_ident: &str, name: Name, new_parent: &Rc<Module>) { - debug!("(building reduced graph for \ - external crate) building external def {}, priv {:?}", - final_ident, vis); + debug!("(building reduced graph for external crate) building external def {}, priv {:?}", + final_ident, + vis); let is_public = vis == hir::Public; let modifiers = if is_public { DefModifiers::PUBLIC } else { DefModifiers::empty() } | DefModifiers::IMPORTABLE; - let is_exported = is_public && match new_parent.def_id.get() { + let is_exported = is_public && + match new_parent.def_id.get() { None => true, - Some(did) => self.external_exports.contains(&did) + Some(did) => self.external_exports.contains(&did), }; if is_exported { self.external_exports.insert(def.def_id()); @@ -731,140 +744,148 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { let kind = match def { DefTy(_, true) => EnumModuleKind, DefTy(_, false) | DefStruct(..) => TypeModuleKind, - _ => NormalModuleKind + _ => NormalModuleKind, }; match def { - DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) | - DefTy(def_id, _) => { - let type_def = child_name_bindings.type_def.borrow().clone(); - match type_def { - Some(TypeNsDef { module_def: Some(module_def), .. }) => { - debug!("(building reduced graph for external crate) \ - already created module"); - module_def.def_id.set(Some(def_id)); - } - Some(_) | None => { - debug!("(building reduced graph for \ - external crate) building module \ - {} {}", final_ident, is_public); - let parent_link = self.get_parent_link(new_parent, name); - - child_name_bindings.define_module(parent_link, - Some(def_id), - kind, - true, - is_public, - DUMMY_SP); - } + DefMod(def_id) | + DefForeignMod(def_id) | + DefStruct(def_id) | + DefTy(def_id, _) => { + let type_def = child_name_bindings.type_def.borrow().clone(); + match type_def { + Some(TypeNsDef { module_def: Some(module_def), .. }) => { + debug!("(building reduced graph for external crate) already created \ + module"); + module_def.def_id.set(Some(def_id)); + } + Some(_) | None => { + debug!("(building reduced graph for external crate) building module {} {}", + final_ident, + is_public); + let parent_link = self.get_parent_link(new_parent, name); + + child_name_bindings.define_module(parent_link, + Some(def_id), + kind, + true, + is_public, + DUMMY_SP); + } + } } - } - _ => {} + _ => {} } match def { - DefMod(_) | DefForeignMod(_) => {} - DefVariant(_, variant_id, is_struct) => { - debug!("(building reduced graph for external crate) building \ - variant {}", - final_ident); - // variants are always treated as importable to allow them to be - // glob used - let modifiers = DefModifiers::PUBLIC | DefModifiers::IMPORTABLE; - if is_struct { - child_name_bindings.define_type(def, DUMMY_SP, modifiers); - // Not adding fields for variants as they are not accessed with a self receiver - self.structs.insert(variant_id, Vec::new()); - } else { - child_name_bindings.define_value(def, DUMMY_SP, modifiers); - } - } - DefFn(ctor_id, true) => { - child_name_bindings.define_value( + DefMod(_) | DefForeignMod(_) => {} + DefVariant(_, variant_id, is_struct) => { + debug!("(building reduced graph for external crate) building variant {}", + final_ident); + // variants are always treated as importable to allow them to be + // glob used + let modifiers = DefModifiers::PUBLIC | DefModifiers::IMPORTABLE; + if is_struct { + child_name_bindings.define_type(def, DUMMY_SP, modifiers); + // Not adding fields for variants as they are not accessed with a self receiver + self.structs.insert(variant_id, Vec::new()); + } else { + child_name_bindings.define_value(def, DUMMY_SP, modifiers); + } + } + DefFn(ctor_id, true) => { + child_name_bindings.define_value( csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id) .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers); - } - DefFn(..) | DefStatic(..) | DefConst(..) | DefAssociatedConst(..) | - DefMethod(..) => { - debug!("(building reduced graph for external \ - crate) building value (fn/static) {}", final_ident); - // impl methods have already been defined with the correct importability modifier - let mut modifiers = match *child_name_bindings.value_def.borrow() { - Some(ref def) => (modifiers & !DefModifiers::IMPORTABLE) | - (def.modifiers & DefModifiers::IMPORTABLE), - None => modifiers - }; - if new_parent.kind.get() != NormalModuleKind { - modifiers = modifiers & !DefModifiers::IMPORTABLE; } - child_name_bindings.define_value(def, DUMMY_SP, modifiers); - } - DefTrait(def_id) => { - debug!("(building reduced graph for external \ - crate) building type {}", final_ident); - - // If this is a trait, add all the trait item names to the trait - // info. - - let trait_item_def_ids = - csearch::get_trait_item_def_ids(&self.session.cstore, def_id); - for trait_item_def in &trait_item_def_ids { - let trait_item_name = csearch::get_trait_name(&self.session.cstore, - trait_item_def.def_id()); - - debug!("(building reduced graph for external crate) ... \ - adding trait item '{}'", - trait_item_name); - - self.trait_item_map.insert((trait_item_name, def_id), - trait_item_def.def_id()); - - if is_exported { - self.external_exports.insert(trait_item_def.def_id()); - } - } - - child_name_bindings.define_type(def, DUMMY_SP, modifiers); - - // Define a module if necessary. - let parent_link = self.get_parent_link(new_parent, name); - child_name_bindings.set_module_kind(parent_link, - Some(def_id), - TraitModuleKind, - true, - is_public, - DUMMY_SP) - } - DefTy(..) | DefAssociatedTy(..) => { - debug!("(building reduced graph for external \ - crate) building type {}", final_ident); - - let modifiers = match new_parent.kind.get() { - NormalModuleKind => modifiers, - _ => modifiers & !DefModifiers::IMPORTABLE - }; - - child_name_bindings.define_type(def, DUMMY_SP, modifiers); - } - DefStruct(def_id) => { - debug!("(building reduced graph for external \ - crate) building type and value for {}", - final_ident); - child_name_bindings.define_type(def, DUMMY_SP, modifiers); - let fields = csearch::get_struct_field_names(&self.session.cstore, def_id); - - if fields.is_empty() { + DefFn(..) | + DefStatic(..) | + DefConst(..) | + DefAssociatedConst(..) | + DefMethod(..) => { + debug!("(building reduced graph for external crate) building value (fn/static) {}", + final_ident); + // impl methods have already been defined with the correct importability + // modifier + let mut modifiers = match *child_name_bindings.value_def.borrow() { + Some(ref def) => (modifiers & !DefModifiers::IMPORTABLE) | + (def.modifiers & DefModifiers::IMPORTABLE), + None => modifiers, + }; + if new_parent.kind.get() != NormalModuleKind { + modifiers = modifiers & !DefModifiers::IMPORTABLE; + } child_name_bindings.define_value(def, DUMMY_SP, modifiers); } + DefTrait(def_id) => { + debug!("(building reduced graph for external crate) building type {}", + final_ident); + + // If this is a trait, add all the trait item names to the trait + // info. + + let trait_item_def_ids = csearch::get_trait_item_def_ids(&self.session.cstore, + def_id); + for trait_item_def in &trait_item_def_ids { + let trait_item_name = csearch::get_trait_name(&self.session.cstore, + trait_item_def.def_id()); + + debug!("(building reduced graph for external crate) ... adding trait item \ + '{}'", + trait_item_name); + + self.trait_item_map.insert((trait_item_name, def_id), trait_item_def.def_id()); + + if is_exported { + self.external_exports.insert(trait_item_def.def_id()); + } + } + + child_name_bindings.define_type(def, DUMMY_SP, modifiers); + + // Define a module if necessary. + let parent_link = self.get_parent_link(new_parent, name); + child_name_bindings.set_module_kind(parent_link, + Some(def_id), + TraitModuleKind, + true, + is_public, + DUMMY_SP) + } + DefTy(..) | DefAssociatedTy(..) => { + debug!("(building reduced graph for external crate) building type {}", + final_ident); - // Record the def ID and fields of this struct. - self.structs.insert(def_id, fields); - } - DefLocal(..) | DefPrimTy(..) | DefTyParam(..) | - DefUse(..) | DefUpvar(..) | - DefLabel(..) | DefSelfTy(..) => { - panic!("didn't expect `{:?}`", def); - } + let modifiers = match new_parent.kind.get() { + NormalModuleKind => modifiers, + _ => modifiers & !DefModifiers::IMPORTABLE, + }; + + child_name_bindings.define_type(def, DUMMY_SP, modifiers); + } + DefStruct(def_id) => { + debug!("(building reduced graph for external crate) building type and value for \ + {}", + final_ident); + child_name_bindings.define_type(def, DUMMY_SP, modifiers); + let fields = csearch::get_struct_field_names(&self.session.cstore, def_id); + + if fields.is_empty() { + child_name_bindings.define_value(def, DUMMY_SP, modifiers); + } + + // Record the def ID and fields of this struct. + self.structs.insert(def_id, fields); + } + DefLocal(..) | + DefPrimTy(..) | + DefTyParam(..) | + DefUse(..) | + DefUpvar(..) | + DefLabel(..) | + DefSelfTy(..) => { + panic!("didn't expect `{:?}`", def); + } } } @@ -894,11 +915,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { }); } _ => { - let child_name_bindings = - self.add_child(name, - root, - OverwriteDuplicates, - DUMMY_SP); + let child_name_bindings = self.add_child(name, + root, + OverwriteDuplicates, + DUMMY_SP); self.handle_external_def(def, def_visibility, @@ -910,12 +930,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { } } DlImpl(_) => { - debug!("(building reduced graph for external crate) \ - ignoring impl"); + debug!("(building reduced graph for external crate) ignoring impl"); } DlField => { - debug!("(building reduced graph for external crate) \ - ignoring field"); + debug!("(building reduced graph for external crate) ignoring field"); } } } @@ -928,7 +946,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { let def_id = match module.def_id.get() { None => { debug!("(populating external module) ... no def ID!"); - return + return; } Some(def_id) => def_id, }; @@ -936,13 +954,13 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { csearch::each_child_of_item(&self.session.cstore, def_id, |def_like, child_name, visibility| { - debug!("(populating external module) ... found ident: {}", - child_name); - self.build_reduced_graph_for_external_crate_def(module, - def_like, - child_name, - visibility) - }); + debug!("(populating external module) ... found ident: {}", + child_name); + self.build_reduced_graph_for_external_crate_def(module, + def_like, + child_name, + visibility) + }); module.populated.set(true) } @@ -977,12 +995,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { id: NodeId, is_public: bool, shadowable: Shadowable) { - module_.imports.borrow_mut().push(ImportDirective::new(module_path, - subclass, - span, - id, - is_public, - shadowable)); + module_.imports + .borrow_mut() + .push(ImportDirective::new(module_path, subclass, span, id, is_public, shadowable)); self.unresolved_imports += 1; if is_public { @@ -1030,9 +1045,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { } } -struct BuildReducedGraphVisitor<'a, 'b:'a, 'tcx:'b> { +struct BuildReducedGraphVisitor<'a, 'b: 'a, 'tcx: 'b> { builder: GraphBuilder<'a, 'b, 'tcx>, - parent: Rc<Module> + parent: Rc<Module>, } impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { @@ -1056,13 +1071,9 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { } pub fn build_reduced_graph(resolver: &mut Resolver, krate: &hir::Crate) { - GraphBuilder { - resolver: resolver - }.build_reduced_graph(krate); + GraphBuilder { resolver: resolver }.build_reduced_graph(krate); } pub fn populate_module_if_necessary(resolver: &mut Resolver, module: &Rc<Module>) { - GraphBuilder { - resolver: resolver - }.populate_module_if_necessary(module); + GraphBuilder { resolver: resolver }.populate_module_if_necessary(module); } diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 4ebc1093a0b..870990f7860 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -31,8 +31,8 @@ use rustc_front::hir; use rustc_front::hir::{ViewPathGlob, ViewPathList, ViewPathSimple}; use rustc_front::visit::{self, Visitor}; -struct UnusedImportCheckVisitor<'a, 'b:'a, 'tcx:'b> { - resolver: &'a mut Resolver<'b, 'tcx> +struct UnusedImportCheckVisitor<'a, 'b: 'a, 'tcx: 'b> { + resolver: &'a mut Resolver<'b, 'tcx>, } // Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver. @@ -51,16 +51,16 @@ impl<'a, 'b, 'tcx:'b> DerefMut for UnusedImportCheckVisitor<'a, 'b, 'tcx> { } impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { - // We have information about whether `use` (import) directives are actually used now. - // If an import is not used at all, we signal a lint error. If an import is only used - // for a single namespace, we remove the other namespace from the recorded privacy - // information. That means in privacy.rs, we will only check imports and namespaces - // which are used. In particular, this means that if an import could name either a - // public or private item, we will check the correct thing, dependent on how the import - // is used. + // We have information about whether `use` (import) directives are actually + // used now. If an import is not used at all, we signal a lint error. If an + // import is only used for a single namespace, we remove the other namespace + // from the recorded privacy information. That means in privacy.rs, we will + // only check imports and namespaces which are used. In particular, this + // means that if an import could name either a public or private item, we + // will check the correct thing, dependent on how the import is used. fn finalize_import(&mut self, id: ast::NodeId, span: Span) { debug!("finalizing import uses for {:?}", - self.session.codemap().span_to_snippet(span)); + self.session.codemap().span_to_snippet(span)); if !self.used_imports.contains(&(id, TypeNS)) && !self.used_imports.contains(&(id, ValueNS)) { @@ -99,14 +99,14 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { // we might have two LastPrivates pointing at the same thing. There is no point // checking both, so lets not check the value one. (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused, - _ => {}, + _ => {} } path_res.last_private = LastImport { value_priv: v_priv, value_used: v_used, type_priv: t_priv, - type_used: t_used + type_used: t_used, }; } } @@ -132,7 +132,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { "unused extern crate".to_string()); } } - }, + } hir::ItemUse(ref p) => { match p.node { ViewPathSimple(_, _) => { diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 4147f2bea48..f35b554d6cf 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -10,9 +10,9 @@ #![allow(non_snake_case)] -// Error messages for EXXXX errors. -// Each message should start and end with a new line, and be wrapped to 80 characters. -// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable. +// Error messages for EXXXX errors. Each message should start and end with a +// new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and +// use `gq` to wrap paragraphs. Use `:set tw=0` to disable. register_long_diagnostics! { E0154: r##" @@ -806,6 +806,15 @@ mod something { pub struct Foo; } ``` + +Or, if you tried to use a module from an external crate, you may have missed +the `extern crate` declaration: + +``` +extern crate homura; // Required to use the `homura` crate + +use homura::Madoka; +``` "##, E0433: r##" diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 80062b371a3..a402d8310f9 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -25,9 +25,13 @@ #![feature(rustc_private)] #![feature(staged_api)] -#[macro_use] extern crate log; -#[macro_use] extern crate syntax; -#[macro_use] #[no_link] extern crate rustc_bitflags; +#[macro_use] +extern crate log; +#[macro_use] +extern crate syntax; +#[macro_use] +#[no_link] +extern crate rustc_bitflags; extern crate rustc_front; extern crate rustc; @@ -198,208 +202,279 @@ pub enum ResolutionError<'a> { AttemptToUseNonConstantValueInConstant, } -fn resolve_error<'b, 'a:'b, 'tcx:'a>(resolver: &'b Resolver<'a, 'tcx>, span: syntax::codemap::Span, - resolution_error: ResolutionError<'b>) { +fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>, + span: syntax::codemap::Span, + resolution_error: ResolutionError<'b>) { if !resolver.emit_errors { return; } match resolution_error { ResolutionError::TypeParametersFromOuterFunction => { - span_err!(resolver.session, span, E0401, "can't use type parameters from \ - outer function; try using a local \ - type parameter instead"); - }, + span_err!(resolver.session, + span, + E0401, + "can't use type parameters from outer function; try using a local type \ + parameter instead"); + } ResolutionError::OuterTypeParameterContext => { - span_err!(resolver.session, span, E0402, - "cannot use an outer type parameter in this context"); - }, + span_err!(resolver.session, + span, + E0402, + "cannot use an outer type parameter in this context"); + } ResolutionError::NameAlreadyUsedInTypeParameterList(name) => { - span_err!(resolver.session, span, E0403, - "the name `{}` is already used for a type \ - parameter in this type parameter list", name); - }, + span_err!(resolver.session, + span, + E0403, + "the name `{}` is already used for a type parameter in this type parameter \ + list", + name); + } ResolutionError::IsNotATrait(name) => { - span_err!(resolver.session, span, E0404, - "`{}` is not a trait", - name); - }, + span_err!(resolver.session, span, E0404, "`{}` is not a trait", name); + } ResolutionError::UndeclaredTraitName(name) => { - span_err!(resolver.session, span, E0405, - "use of undeclared trait name `{}`", - name); - }, + span_err!(resolver.session, + span, + E0405, + "use of undeclared trait name `{}`", + name); + } ResolutionError::UndeclaredAssociatedType => { span_err!(resolver.session, span, E0406, "undeclared associated type"); - }, + } ResolutionError::MethodNotMemberOfTrait(method, trait_) => { - span_err!(resolver.session, span, E0407, - "method `{}` is not a member of trait `{}`", - method, - trait_); - }, + span_err!(resolver.session, + span, + E0407, + "method `{}` is not a member of trait `{}`", + method, + trait_); + } ResolutionError::TypeNotMemberOfTrait(type_, trait_) => { - span_err!(resolver.session, span, E0437, - "type `{}` is not a member of trait `{}`", - type_, - trait_); - }, + span_err!(resolver.session, + span, + E0437, + "type `{}` is not a member of trait `{}`", + type_, + trait_); + } ResolutionError::ConstNotMemberOfTrait(const_, trait_) => { - span_err!(resolver.session, span, E0438, - "const `{}` is not a member of trait `{}`", - const_, - trait_); - }, + span_err!(resolver.session, + span, + E0438, + "const `{}` is not a member of trait `{}`", + const_, + trait_); + } ResolutionError::VariableNotBoundInPattern(variable_name, pattern_number) => { - span_err!(resolver.session, span, E0408, - "variable `{}` from pattern #1 is not bound in pattern #{}", - variable_name, - pattern_number); - }, + span_err!(resolver.session, + span, + E0408, + "variable `{}` from pattern #1 is not bound in pattern #{}", + variable_name, + pattern_number); + } ResolutionError::VariableBoundWithDifferentMode(variable_name, pattern_number) => { - span_err!(resolver.session, span, E0409, - "variable `{}` is bound with different \ - mode in pattern #{} than in pattern #1", - variable_name, - pattern_number); - }, + span_err!(resolver.session, + span, + E0409, + "variable `{}` is bound with different mode in pattern #{} than in pattern \ + #1", + variable_name, + pattern_number); + } ResolutionError::VariableNotBoundInParentPattern(variable_name, pattern_number) => { - span_err!(resolver.session, span, E0410, - "variable `{}` from pattern #{} is not bound in pattern #1", - variable_name, - pattern_number); - }, + span_err!(resolver.session, + span, + E0410, + "variable `{}` from pattern #{} is not bound in pattern #1", + variable_name, + pattern_number); + } ResolutionError::SelfUsedOutsideImplOrTrait => { - span_err!(resolver.session, span, E0411, "use of `Self` outside of an impl or trait"); - }, + span_err!(resolver.session, + span, + E0411, + "use of `Self` outside of an impl or trait"); + } ResolutionError::UseOfUndeclared(kind, name) => { - span_err!(resolver.session, span, E0412, - "use of undeclared {} `{}`", - kind, - name); - }, + span_err!(resolver.session, + span, + E0412, + "use of undeclared {} `{}`", + kind, + name); + } ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(name) => { - span_err!(resolver.session, span, E0413, - "declaration of `{}` shadows an enum variant or unit-like struct in \ - scope", - name); - }, + span_err!(resolver.session, + span, + E0413, + "declaration of `{}` shadows an enum variant or unit-like struct in scope", + name); + } ResolutionError::OnlyIrrefutablePatternsAllowedHere(did, name) => { - span_err!(resolver.session, span, E0414, "only irrefutable patterns allowed here"); - resolver.session.span_note(span, "there already is a constant in scope \ - sharing the same name as this pattern"); + span_err!(resolver.session, + span, + E0414, + "only irrefutable patterns allowed here"); + resolver.session.span_note(span, + "there already is a constant in scope sharing the same \ + name as this pattern"); if let Some(sp) = resolver.ast_map.span_if_local(did) { resolver.session.span_note(sp, "constant defined here"); } if let Some(directive) = resolver.current_module .import_resolutions - .borrow().get(&name) { + .borrow() + .get(&name) { let item = resolver.ast_map.expect_item(directive.value_id); resolver.session.span_note(item.span, "constant imported here"); } - }, + } ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => { - span_err!(resolver.session, span, E0415, - "identifier `{}` is bound more than once in this parameter list", - identifier); - }, + span_err!(resolver.session, + span, + E0415, + "identifier `{}` is bound more than once in this parameter list", + identifier); + } ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => { - span_err!(resolver.session, span, E0416, - "identifier `{}` is bound more than once in the same pattern", - identifier); - }, + span_err!(resolver.session, + span, + E0416, + "identifier `{}` is bound more than once in the same pattern", + identifier); + } ResolutionError::StaticVariableReference => { - span_err!(resolver.session, span, E0417, "static variables cannot be \ - referenced in a pattern, \ - use a `const` instead"); - }, + span_err!(resolver.session, + span, + E0417, + "static variables cannot be referenced in a pattern, use a `const` instead"); + } ResolutionError::NotAnEnumVariantStructOrConst(name) => { - span_err!(resolver.session, span, E0418, - "`{}` is not an enum variant, struct or const", - name); - }, + span_err!(resolver.session, + span, + E0418, + "`{}` is not an enum variant, struct or const", + name); + } ResolutionError::UnresolvedEnumVariantStructOrConst(name) => { - span_err!(resolver.session, span, E0419, - "unresolved enum variant, struct or const `{}`", - name); - }, + span_err!(resolver.session, + span, + E0419, + "unresolved enum variant, struct or const `{}`", + name); + } ResolutionError::NotAnAssociatedConst(name) => { - span_err!(resolver.session, span, E0420, - "`{}` is not an associated const", - name); - }, + span_err!(resolver.session, + span, + E0420, + "`{}` is not an associated const", + name); + } ResolutionError::UnresolvedAssociatedConst(name) => { - span_err!(resolver.session, span, E0421, - "unresolved associated const `{}`", - name); - }, + span_err!(resolver.session, + span, + E0421, + "unresolved associated const `{}`", + name); + } ResolutionError::DoesNotNameAStruct(name) => { - span_err!(resolver.session, span, E0422, "`{}` does not name a structure", name); - }, + span_err!(resolver.session, + span, + E0422, + "`{}` does not name a structure", + name); + } ResolutionError::StructVariantUsedAsFunction(path_name) => { - span_err!(resolver.session, span, E0423, - "`{}` is the name of a struct or struct variant, \ - but this expression \ - uses it like a function name", - path_name); - }, + span_err!(resolver.session, + span, + E0423, + "`{}` is the name of a struct or struct variant, but this expression uses \ + it like a function name", + path_name); + } ResolutionError::SelfNotAvailableInStaticMethod => { - span_err!(resolver.session, span, E0424, "`self` is not available in a static method. \ - Maybe a `self` argument is missing?"); - }, + span_err!(resolver.session, + span, + E0424, + "`self` is not available in a static method. Maybe a `self` argument is \ + missing?"); + } ResolutionError::UnresolvedName(path, name) => { - span_err!(resolver.session, span, E0425, - "unresolved name `{}`{}", - path, - name); - }, + span_err!(resolver.session, + span, + E0425, + "unresolved name `{}`{}", + path, + name); + } ResolutionError::UndeclaredLabel(name) => { - span_err!(resolver.session, span, E0426, - "use of undeclared label `{}`", - name); - }, + span_err!(resolver.session, + span, + E0426, + "use of undeclared label `{}`", + name); + } ResolutionError::CannotUseRefBindingModeWith(descr) => { - span_err!(resolver.session, span, E0427, - "cannot use `ref` binding mode with {}", - descr); - }, + span_err!(resolver.session, + span, + E0427, + "cannot use `ref` binding mode with {}", + descr); + } ResolutionError::DuplicateDefinition(namespace, name) => { - span_err!(resolver.session, span, E0428, - "duplicate definition of {} `{}`", - namespace, - name); - }, + span_err!(resolver.session, + span, + E0428, + "duplicate definition of {} `{}`", + namespace, + name); + } ResolutionError::SelfImportsOnlyAllowedWithin => { - span_err!(resolver.session, span, E0429, "{}", - "`self` imports are only allowed within a { } list"); - }, + span_err!(resolver.session, + span, + E0429, + "{}", + "`self` imports are only allowed within a { } list"); + } ResolutionError::SelfImportCanOnlyAppearOnceInTheList => { - span_err!(resolver.session, span, E0430, - "`self` import can only appear once in the list"); - }, + span_err!(resolver.session, + span, + E0430, + "`self` import can only appear once in the list"); + } ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => { - span_err!(resolver.session, span, E0431, - "`self` import can only appear in an import list with a \ - non-empty prefix"); + span_err!(resolver.session, + span, + E0431, + "`self` import can only appear in an import list with a non-empty prefix"); } ResolutionError::UnresolvedImport(name) => { let msg = match name { Some((n, p)) => format!("unresolved import `{}`{}", n, p), - None => "unresolved import".to_owned() + None => "unresolved import".to_owned(), }; span_err!(resolver.session, span, E0432, "{}", msg); - }, + } ResolutionError::FailedToResolve(msg) => { span_err!(resolver.session, span, E0433, "failed to resolve. {}", msg); - }, + } ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => { - span_err!(resolver.session, span, E0434, "{}", - "can't capture dynamic environment in a fn item; \ - use the || { ... } closure form instead"); - }, - ResolutionError::AttemptToUseNonConstantValueInConstant =>{ - span_err!(resolver.session, span, E0435, - "attempt to use a non-constant value in a constant"); - }, + span_err!(resolver.session, + span, + E0434, + "{}", + "can't capture dynamic environment in a fn item; use the || { ... } \ + closure form instead"); + } + ResolutionError::AttemptToUseNonConstantValueInConstant => { + span_err!(resolver.session, + span, + E0435, + "attempt to use a non-constant value in a constant"); + } } } @@ -422,7 +497,7 @@ enum PatternBindingMode { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum Namespace { TypeNS, - ValueNS + ValueNS, } /// A NamespaceResult represents the result of resolving an import in @@ -439,20 +514,20 @@ enum NamespaceResult { UnboundResult, /// Means that resolve has determined that the name is bound in the Module /// argument, and specified by the NameBindings argument. - BoundResult(Rc<Module>, Rc<NameBindings>) + BoundResult(Rc<Module>, Rc<NameBindings>), } impl NamespaceResult { fn is_unknown(&self) -> bool { match *self { UnknownResult => true, - _ => false + _ => false, } } fn is_unbound(&self) -> bool { match *self { UnboundResult => true, - _ => false + _ => false, } } } @@ -492,16 +567,19 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { fn visit_generics(&mut self, generics: &Generics) { self.resolve_generics(generics); } - fn visit_poly_trait_ref(&mut self, - tref: &hir::PolyTraitRef, - m: &hir::TraitBoundModifier) { + fn visit_poly_trait_ref(&mut self, tref: &hir::PolyTraitRef, m: &hir::TraitBoundModifier) { match self.resolve_trait_reference(tref.trait_ref.ref_id, &tref.trait_ref.path, 0) { Ok(def) => self.record_def(tref.trait_ref.ref_id, def), - Err(_) => { /* error already reported */ } + Err(_) => { + // error already reported + } } visit::walk_poly_trait_ref(self, tref, m); } - fn visit_variant(&mut self, variant: &hir::Variant, generics: &Generics, item_id: ast::NodeId) { + fn visit_variant(&mut self, + variant: &hir::Variant, + generics: &Generics, + item_id: ast::NodeId) { execute_callback!(hir_map::Node::NodeVariant(variant), self); if let Some(ref dis_expr) = variant.node.disr_expr { // resolve the discriminator expr as a constant @@ -511,8 +589,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { } // `visit::walk_variant` without the discriminant expression. - self.visit_variant_data(&variant.node.data, variant.node.name, - generics, item_id, variant.span); + self.visit_variant_data(&variant.node.data, + variant.node.name, + generics, + item_id, + variant.span); } fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem) { execute_callback!(hir_map::Node::NodeForeignItem(foreign_item), self); @@ -520,7 +601,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { ForeignItemFn(_, ref generics) => { HasTypeParameters(generics, FnSpace, ItemRibKind) } - ForeignItemStatic(..) => NoTypeParameters + ForeignItemStatic(..) => NoTypeParameters, }; self.with_type_parameter_rib(type_parameters, |this| { visit::walk_foreign_item(this, foreign_item); @@ -542,7 +623,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { self.visit_explicit_self(&sig.explicit_self); MethodRibKind } - FnKind::Closure(..) => ClosureRibKind(node_id) + FnKind::Closure(..) => ClosureRibKind(node_id), }; self.resolve_function(rib_kind, declaration, block); } @@ -551,14 +632,17 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { type ErrorMessage = Option<(Span, String)>; enum ResolveResult<T> { - Failed(ErrorMessage), // Failed to resolve the name, optional helpful error message. - Indeterminate, // Couldn't determine due to unresolved globs. - Success(T) // Successfully resolved the import. + Failed(ErrorMessage), // Failed to resolve the name, optional helpful error message. + Indeterminate, // Couldn't determine due to unresolved globs. + Success(T), // Successfully resolved the import. } impl<T> ResolveResult<T> { fn success(&self) -> bool { - match *self { Success(_) => true, _ => false } + match *self { + Success(_) => true, + _ => false, + } } } @@ -574,16 +658,15 @@ enum FallbackSuggestion { #[derive(Copy, Clone)] enum TypeParameters<'a> { NoTypeParameters, - HasTypeParameters( - // Type parameters. - &'a Generics, + HasTypeParameters(// Type parameters. + &'a Generics, - // Identifies the things that these parameters - // were declared on (type, fn, etc) - ParamSpace, + // Identifies the things that these parameters + // were declared on (type, fn, etc) + ParamSpace, - // The kind of the rib used for type parameters. - RibKind) + // The kind of the rib used for type parameters. + RibKind), } // The rib kind controls the translation of local @@ -607,18 +690,18 @@ enum RibKind { ItemRibKind, // We're in a constant item. Can't refer to dynamic stuff. - ConstantItemRibKind + ConstantItemRibKind, } #[derive(Copy, Clone)] enum UseLexicalScopeFlag { DontUseLexicalScope, - UseLexicalScope + UseLexicalScope, } enum ModulePrefixResult { NoPrefixFound, - PrefixFound(Rc<Module>, usize) + PrefixFound(Rc<Module>, usize), } #[derive(Copy, Clone)] @@ -644,7 +727,7 @@ enum NameSearchType { enum BareIdentifierPatternResolution { FoundStructOrEnumVariant(Def, LastPrivate), FoundConst(Def, LastPrivate, Name), - BareIdentifierPatternUnresolved + BareIdentifierPatternUnresolved, } /// One local scope. @@ -658,7 +741,7 @@ impl Rib { fn new(kind: RibKind) -> Rib { Rib { bindings: HashMap::new(), - kind: kind + kind: kind, } } } @@ -666,14 +749,14 @@ impl Rib { /// A definition along with the index of the rib it was found on struct LocalDef { ribs: Option<(Namespace, usize)>, - def: Def + def: Def, } impl LocalDef { fn from_def(def: Def) -> Self { LocalDef { ribs: None, - def: def + def: def, } } } @@ -683,7 +766,7 @@ impl LocalDef { enum ParentLink { NoParentLink, ModuleParentLink(Weak<Module>, Name), - BlockParentLink(Weak<Module>, NodeId) + BlockParentLink(Weak<Module>, NodeId), } /// The type of module this is. @@ -808,10 +891,15 @@ impl Module { impl fmt::Debug for Module { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}, kind: {:?}, {}", + write!(f, + "{:?}, kind: {:?}, {}", self.def_id, self.kind, - if self.is_public { "public" } else { "private" } ) + if self.is_public { + "public" + } else { + "private" + }) } } @@ -829,7 +917,7 @@ struct TypeNsDef { modifiers: DefModifiers, // see note in ImportResolution about how to use this module_def: Option<Rc<Module>>, type_def: Option<Def>, - type_span: Option<Span> + type_span: Option<Span>, } // Records a possibly-private value definition. @@ -844,8 +932,8 @@ struct ValueNsDef { // bound to. #[derive(Debug)] pub struct NameBindings { - type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace. - value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace. + type_def: RefCell<Option<TypeNsDef>>, // < Meaning in type namespace. + value_def: RefCell<Option<ValueNsDef>>, // < Meaning in value namespace. } impl NameBindings { @@ -870,11 +958,7 @@ impl NameBindings { } else { DefModifiers::empty() } | DefModifiers::IMPORTABLE; - let module_ = Rc::new(Module::new(parent_link, - def_id, - kind, - external, - is_public)); + let module_ = Rc::new(Module::new(parent_link, def_id, kind, external, is_public)); let type_def = self.type_def.borrow().clone(); match type_def { None => { @@ -882,7 +966,7 @@ impl NameBindings { modifiers: modifiers, module_def: Some(module_), type_def: None, - type_span: Some(sp) + type_span: Some(sp), }); } Some(type_def) => { @@ -890,7 +974,7 @@ impl NameBindings { modifiers: modifiers, module_def: Some(module_), type_span: Some(sp), - type_def: type_def.type_def + type_def: type_def.type_def, }); } } @@ -912,11 +996,7 @@ impl NameBindings { let type_def = self.type_def.borrow().clone(); match type_def { None => { - let module = Module::new(parent_link, - def_id, - kind, - external, - is_public); + let module = Module::new(parent_link, def_id, kind, external, is_public); *self.type_def.borrow_mut() = Some(TypeNsDef { modifiers: modifiers, module_def: Some(Rc::new(module)), @@ -927,11 +1007,7 @@ impl NameBindings { Some(type_def) => { match type_def.module_def { None => { - let module = Module::new(parent_link, - def_id, - kind, - external, - is_public); + let module = Module::new(parent_link, def_id, kind, external, is_public); *self.type_def.borrow_mut() = Some(TypeNsDef { modifiers: modifiers, module_def: Some(Rc::new(module)), @@ -947,7 +1023,9 @@ impl NameBindings { /// Records a type definition. fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) { - debug!("defining type for def {:?} with modifiers {:?}", def, modifiers); + debug!("defining type for def {:?} with modifiers {:?}", + def, + modifiers); // Merges the type with the existing type def or creates a new one. let type_def = self.type_def.borrow().clone(); match type_def { @@ -972,7 +1050,9 @@ impl NameBindings { /// Records a value definition. fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) { - debug!("defining value for def {:?} with modifiers {:?}", def, modifiers); + debug!("defining value for def {:?} with modifiers {:?}", + def, + modifiers); *self.value_def.borrow_mut() = Some(ValueNsDef { def: def, value_span: Some(sp), @@ -984,7 +1064,7 @@ impl NameBindings { fn get_module_if_available(&self) -> Option<Rc<Module>> { match *self.type_def.borrow() { Some(ref type_def) => type_def.module_def.clone(), - None => None + None => None, } } @@ -993,17 +1073,16 @@ impl NameBindings { fn get_module(&self) -> Rc<Module> { match self.get_module_if_available() { None => { - panic!("get_module called on a node with no module \ - definition!") + panic!("get_module called on a node with no module definition!") } - Some(module_def) => module_def + Some(module_def) => module_def, } } fn defined_in_namespace(&self, namespace: Namespace) -> bool { match namespace { - TypeNS => return self.type_def.borrow().is_some(), - ValueNS => return self.value_def.borrow().is_some() + TypeNS => return self.type_def.borrow().is_some(), + ValueNS => return self.value_def.borrow().is_some(), } } @@ -1014,11 +1093,13 @@ impl NameBindings { fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool { match namespace { TypeNS => match *self.type_def.borrow() { - Some(ref def) => def.modifiers.contains(modifiers), None => false + Some(ref def) => def.modifiers.contains(modifiers), + None => false, }, ValueNS => match *self.value_def.borrow() { - Some(ref def) => def.modifiers.contains(modifiers), None => false - } + Some(ref def) => def.modifiers.contains(modifiers), + None => false, + }, } } @@ -1048,7 +1129,7 @@ impl NameBindings { ValueNS => { match *self.value_def.borrow() { None => None, - Some(value_def) => Some(value_def.def) + Some(value_def) => Some(value_def.def), } } } @@ -1057,16 +1138,16 @@ impl NameBindings { fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> { if self.defined_in_namespace(namespace) { match namespace { - TypeNS => { + TypeNS => { match *self.type_def.borrow() { None => None, - Some(ref type_def) => type_def.type_span + Some(ref type_def) => type_def.type_span, } } ValueNS => { match *self.value_def.borrow() { None => None, - Some(ref value_def) => value_def.value_span + Some(ref value_def) => value_def.value_span, } } } @@ -1077,7 +1158,7 @@ impl NameBindings { fn is_public(&self, namespace: Namespace) -> bool { match namespace { - TypeNS => { + TypeNS => { let type_def = self.type_def.borrow(); type_def.as_ref().unwrap().modifiers.contains(DefModifiers::PUBLIC) } @@ -1096,25 +1177,23 @@ struct PrimitiveTypeTable { impl PrimitiveTypeTable { fn new() -> PrimitiveTypeTable { - let mut table = PrimitiveTypeTable { - primitive_types: HashMap::new() - }; - - table.intern("bool", TyBool); - table.intern("char", TyChar); - table.intern("f32", TyFloat(TyF32)); - table.intern("f64", TyFloat(TyF64)); - table.intern("isize", TyInt(TyIs)); - table.intern("i8", TyInt(TyI8)); - table.intern("i16", TyInt(TyI16)); - table.intern("i32", TyInt(TyI32)); - table.intern("i64", TyInt(TyI64)); - table.intern("str", TyStr); - table.intern("usize", TyUint(TyUs)); - table.intern("u8", TyUint(TyU8)); - table.intern("u16", TyUint(TyU16)); - table.intern("u32", TyUint(TyU32)); - table.intern("u64", TyUint(TyU64)); + let mut table = PrimitiveTypeTable { primitive_types: HashMap::new() }; + + table.intern("bool", TyBool); + table.intern("char", TyChar); + table.intern("f32", TyFloat(TyF32)); + table.intern("f64", TyFloat(TyF64)); + table.intern("isize", TyInt(TyIs)); + table.intern("i8", TyInt(TyI8)); + table.intern("i16", TyInt(TyI16)); + table.intern("i32", TyInt(TyI32)); + table.intern("i64", TyInt(TyI64)); + table.intern("str", TyStr); + table.intern("usize", TyUint(TyUs)); + table.intern("u8", TyUint(TyU8)); + table.intern("u16", TyUint(TyU16)); + table.intern("u32", TyUint(TyU32)); + table.intern("u64", TyUint(TyU64)); table } @@ -1125,7 +1204,7 @@ impl PrimitiveTypeTable { } /// The main resolver class. -pub struct Resolver<'a, 'tcx:'a> { +pub struct Resolver<'a, 'tcx: 'a> { session: &'a Session, ast_map: &'a hir_map::Map<'tcx>, @@ -1186,20 +1265,20 @@ pub struct Resolver<'a, 'tcx:'a> { // The intention is that the callback modifies this flag. // Once set, the resolver falls out of the walk, preserving the ribs. resolved: bool, - } #[derive(PartialEq)] enum FallbackChecks { Everything, - OnlyTraitAndStatics + OnlyTraitAndStatics, } impl<'a, 'tcx> Resolver<'a, 'tcx> { fn new(session: &'a Session, ast_map: &'a hir_map::Map<'tcx>, crate_span: Span, - make_glob_map: MakeGlobMap) -> Resolver<'a, 'tcx> { + make_glob_map: MakeGlobMap) + -> Resolver<'a, 'tcx> { let graph_root = NameBindings::new(); let root_def_id = ast_map.local_def_id(CRATE_NODE_ID); @@ -1219,7 +1298,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // The outermost module has def ID 0; this is not reflected in the // AST. - graph_root: graph_root, trait_item_map: FnvHashMap(), @@ -1252,7 +1330,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { callback: None, resolved: false, - } } @@ -1285,7 +1362,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { modifiers: DefModifiers::IMPORTABLE, module_def: Some(module), type_def: None, - type_span: None + type_span: None, })), value_def: RefCell::new(None), } @@ -1298,10 +1375,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { name: Name, span: Span) { if module.external_module_children.borrow().contains_key(&name) { - span_err!(self.session, span, E0259, - "an external crate named `{}` has already \ - been imported into this module", - name); + span_err!(self.session, + span, + E0259, + "an external crate named `{}` has already been imported into this module", + name); } } @@ -1311,11 +1389,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { name: Name, span: Span) { if module.external_module_children.borrow().contains_key(&name) { - span_err!(self.session, span, E0260, - "the name `{}` conflicts with an external \ - crate that has been imported into this \ - module", - name); + span_err!(self.session, + span, + E0260, + "the name `{}` conflicts with an external crate that has been imported \ + into this module", + name); } } @@ -1327,17 +1406,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { span: Span, name_search_type: NameSearchType, lp: LastPrivate) - -> ResolveResult<(Rc<Module>, LastPrivate)> { - fn search_parent_externals(needle: Name, module: &Rc<Module>) - -> Option<Rc<Module>> { + -> ResolveResult<(Rc<Module>, LastPrivate)> { + fn search_parent_externals(needle: Name, module: &Rc<Module>) -> Option<Rc<Module>> { match module.external_module_children.borrow().get(&needle) { Some(_) => Some(module.clone()), None => match module.parent_link { ModuleParentLink(ref parent, _) => { search_parent_externals(needle, &parent.upgrade().unwrap()) } - _ => None - } + _ => None, + }, } } @@ -1363,13 +1441,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let msg = if "???" == &module_name[..] { span.hi = span.lo + Pos::from_usize(segment_name.len()); - match search_parent_externals(name, - &self.current_module) { + match search_parent_externals(name, &self.current_module) { Some(module) => { let path_str = names_to_string(module_path); let target_mod_str = module_to_string(&*module); - let current_mod_str = - module_to_string(&*self.current_module); + let current_mod_str = module_to_string(&*self.current_module); let prefix = if target_mod_str == current_mod_str { "self::".to_string() @@ -1378,23 +1454,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; format!("Did you mean `{}{}`?", prefix, path_str) - }, - None => format!("Maybe a missing `extern crate {}`?", - segment_name), + } + None => format!("Maybe a missing `extern crate {}`?", segment_name), } } else { - format!("Could not find `{}` in `{}`", - segment_name, - module_name) + format!("Could not find `{}` in `{}`", segment_name, module_name) }; return Failed(Some((span, msg))); } Failed(err) => return Failed(err), Indeterminate => { - debug!("(resolving module path for import) module \ - resolution is indeterminate: {}", - name); + debug!("(resolving module path for import) module resolution is \ + indeterminate: {}", + name); return Indeterminate; } Success((target, used_proxy)) => { @@ -1404,8 +1477,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some(ref type_def) => { match type_def.module_def { None => { - let msg = format!("Not a module `{}`", - name); + let msg = format!("Not a module `{}`", name); return Failed(Some((span, msg))); } @@ -1430,8 +1502,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } None => { // There are no type bindings at all. - let msg = format!("Not a module `{}`", - name); + let msg = format!("Not a module `{}`", name); return Failed(Some((span, msg))); } } @@ -1464,8 +1535,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { module_to_string(&*module_)); // Resolve the module prefix, if any. - let module_prefix_result = self.resolve_module_prefix(module_.clone(), - module_path); + let module_prefix_result = self.resolve_module_prefix(module_.clone(), module_path); let search_module; let start_index; @@ -1477,21 +1547,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match mpath.rfind(':') { Some(idx) => { let msg = format!("Could not find `{}` in `{}`", - // idx +- 1 to account for the - // colons on either side - &mpath[idx + 1..], - &mpath[..idx - 1]); + // idx +- 1 to account for the + // colons on either side + &mpath[idx + 1..], + &mpath[..idx - 1]); return Failed(Some((span, msg))); - }, + } None => { - return Failed(None) + return Failed(None); } } } Failed(err) => return Failed(err), Indeterminate => { - debug!("(resolving module path for import) indeterminate; \ - bailing"); + debug!("(resolving module path for import) indeterminate; bailing"); return Indeterminate; } Success(NoPrefixFound) => { @@ -1510,12 +1579,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // This is not a crate-relative path. We resolve the // first component of the path in the current lexical // scope and then proceed to resolve below that. - match self.resolve_module_in_lexical_scope(module_, - module_path[0]) { + match self.resolve_module_in_lexical_scope(module_, module_path[0]) { Failed(err) => return Failed(err), Indeterminate => { - debug!("(resolving module path for import) \ - indeterminate; bailing"); + debug!("(resolving module path for import) indeterminate; bailing"); return Indeterminate; } Success(containing_module) => { @@ -1550,9 +1617,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { module_: Rc<Module>, name: Name, namespace: Namespace) - -> ResolveResult<(Target, bool)> { - debug!("(resolving item in lexical scope) resolving `{}` in \ - namespace {:?} in `{}`", + -> ResolveResult<(Target, bool)> { + debug!("(resolving item in lexical scope) resolving `{}` in namespace {:?} in `{}`", name, namespace, module_to_string(&*module_)); @@ -1562,15 +1628,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { build_reduced_graph::populate_module_if_necessary(self, &module_); match module_.children.borrow().get(&name) { - Some(name_bindings) - if name_bindings.defined_in_namespace(namespace) => { + Some(name_bindings) if name_bindings.defined_in_namespace(namespace) => { debug!("top name bindings succeeded"); return Success((Target::new(module_.clone(), name_bindings.clone(), Shadowable::Never), - false)); + false)); + } + Some(_) | None => { + // Not found; continue. } - Some(_) | None => { /* Not found; continue. */ } } // Now check for its import directives. We don't have to have resolved @@ -1581,19 +1648,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match (*import_resolution).target_for_namespace(namespace) { None => { // Not found; continue. - debug!("(resolving item in lexical scope) found \ - import resolution, but not in namespace {:?}", + debug!("(resolving item in lexical scope) found import resolution, but not \ + in namespace {:?}", namespace); } Some(target) => { - debug!("(resolving item in lexical scope) using \ - import resolution"); + debug!("(resolving item in lexical scope) using import resolution"); // track used imports and extern crates as well let id = import_resolution.id(namespace); self.used_imports.insert((id, namespace)); self.record_import_use(id, name); if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() { - self.used_crates.insert(kid); + self.used_crates.insert(kid); } return Success((target, false)); } @@ -1605,12 +1671,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // FIXME (21114): In principle unclear `child` *has* to be lifted. let child = module_.external_module_children.borrow().get(&name).cloned(); if let Some(module) = child { - let name_bindings = - Rc::new(Resolver::create_name_bindings_from_module(module)); + let name_bindings = Rc::new(Resolver::create_name_bindings_from_module(module)); debug!("lower name bindings succeeded"); - return Success((Target::new(module_, - name_bindings, - Shadowable::Never), + return Success((Target::new(module_, name_bindings, Shadowable::Never), false)); } } @@ -1622,18 +1685,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match search_module.parent_link.clone() { NoParentLink => { // No more parents. This module was unresolved. - debug!("(resolving item in lexical scope) unresolved \ - module"); + debug!("(resolving item in lexical scope) unresolved module"); return Failed(None); } ModuleParentLink(parent_module_node, _) => { match search_module.kind.get() { NormalModuleKind => { // We stop the search here. - debug!("(resolving item in lexical \ - scope) unresolved module: not \ - searching through module \ - parents"); + debug!("(resolving item in lexical scope) unresolved module: not \ + searching through module parents"); return Failed(None); } TraitModuleKind | @@ -1657,20 +1717,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { true) { Failed(Some((span, msg))) => { resolve_error(self, span, ResolutionError::FailedToResolve(&*msg)); - }, + } Failed(None) => (), // Continue up the search chain. Indeterminate => { // We couldn't see through the higher scope because of an // unresolved import higher up. Bail. - debug!("(resolving item in lexical scope) indeterminate \ - higher scope; bailing"); + debug!("(resolving item in lexical scope) indeterminate higher scope; bailing"); return Indeterminate; } Success((target, used_reexport)) => { // We found the module. - debug!("(resolving item in lexical scope) found name \ - in module, done"); + debug!("(resolving item in lexical scope) found name in module, done"); return Success((target, used_reexport)); } } @@ -1681,7 +1739,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_module_in_lexical_scope(&mut self, module_: Rc<Module>, name: Name) - -> ResolveResult<Rc<Module>> { + -> ResolveResult<Rc<Module>> { // If this module is an anonymous module, resolve the item in the // lexical scope. Otherwise, resolve the item from the crate root. let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS); @@ -1692,9 +1750,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some(ref type_def) => { match type_def.module_def { None => { - debug!("!!! (resolving module in lexical \ - scope) module wasn't actually a \ - module!"); + debug!("!!! (resolving module in lexical scope) module wasn't \ + actually a module!"); return Failed(None); } Some(ref module_def) => { @@ -1704,14 +1761,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } None => { debug!("!!! (resolving module in lexical scope) module + \ wasn't actually a module!"); return Failed(None); } } } Indeterminate => { - debug!("(resolving module in lexical scope) indeterminate; \ - bailing"); + debug!("(resolving module in lexical scope) indeterminate; bailing"); return Indeterminate; } Failed(err) => { @@ -1722,8 +1779,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } /// Returns the nearest normal module parent of the given module. - fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>) - -> Option<Rc<Module>> { + fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>) -> Option<Rc<Module>> { let mut module_ = module_; loop { match module_.parent_link.clone() { @@ -1745,8 +1801,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// Returns the nearest normal module parent of the given module, or the /// module itself if it is a normal module. - fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>) - -> Rc<Module> { + fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>) -> Rc<Module> { match module_.kind.get() { NormalModuleKind => return module_, TraitModuleKind | @@ -1755,7 +1810,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { AnonymousModuleKind => { match self.get_nearest_normal_module_parent(module_.clone()) { None => module_, - Some(new_module) => new_module + Some(new_module) => new_module, } } } @@ -1767,7 +1822,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_module_prefix(&mut self, module_: Rc<Module>, module_path: &[Name]) - -> ResolveResult<ModulePrefixResult> { + -> ResolveResult<ModulePrefixResult> { // Start at the current module if we see `self` or `super`, or at the // top of the crate otherwise. let mut i = match &*module_path[0].as_str() { @@ -1817,13 +1872,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { build_reduced_graph::populate_module_if_necessary(self, &module_); match module_.children.borrow().get(&name) { - Some(name_bindings) - if name_bindings.defined_in_namespace(namespace) => { + Some(name_bindings) if name_bindings.defined_in_namespace(namespace) => { debug!("(resolving name in module) found node as child"); return Success((Target::new(module_.clone(), name_bindings.clone(), Shadowable::Never), - false)); + false)); } Some(_) | None => { // Continue. @@ -1840,24 +1894,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Check the list of resolved imports. match module_.import_resolutions.borrow().get(&name) { - Some(import_resolution) if allow_private_imports || - import_resolution.is_public => { + Some(import_resolution) if allow_private_imports || import_resolution.is_public => { - if import_resolution.is_public && - import_resolution.outstanding_references != 0 { - debug!("(resolving name in module) import \ - unresolved; bailing out"); + if import_resolution.is_public && import_resolution.outstanding_references != 0 { + debug!("(resolving name in module) import unresolved; bailing out"); return Indeterminate; } match import_resolution.target_for_namespace(namespace) { None => { - debug!("(resolving name in module) name found, \ - but not in namespace {:?}", + debug!("(resolving name in module) name found, but not in namespace {:?}", namespace); } Some(target) => { - debug!("(resolving name in module) resolved to \ - import"); + debug!("(resolving name in module) resolved to import"); // track used imports and extern crates as well let id = import_resolution.id(namespace); self.used_imports.insert((id, namespace)); @@ -1877,18 +1926,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // FIXME (21114): In principle unclear `child` *has* to be lifted. let child = module_.external_module_children.borrow().get(&name).cloned(); if let Some(module) = child { - let name_bindings = - Rc::new(Resolver::create_name_bindings_from_module(module)); - return Success((Target::new(module_, - name_bindings, - Shadowable::Never), + let name_bindings = Rc::new(Resolver::create_name_bindings_from_module(module)); + return Success((Target::new(module_, name_bindings, Shadowable::Never), false)); } } // We're out of luck. - debug!("(resolving name in module) failed to resolve `{}`", - name); + debug!("(resolving name in module) failed to resolve `{}`", name); return Failed(None); } @@ -1939,8 +1984,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // generate a fake "implementation scope" containing all the // implementations thus found, for compatibility with old resolve pass. - fn with_scope<F>(&mut self, name: Option<Name>, f: F) where - F: FnOnce(&mut Resolver), + fn with_scope<F>(&mut self, name: Option<Name>, f: F) + where F: FnOnce(&mut Resolver) { let orig_module = self.current_module.clone(); @@ -1961,8 +2006,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some(name_bindings) => { match (*name_bindings).get_module_if_available() { None => { - debug!("!!! (with scope) didn't find module \ - for `{}` in `{}`", + debug!("!!! (with scope) didn't find module for `{}` in `{}`", name, module_to_string(&*orig_module)); } @@ -1990,12 +2034,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } _ => { // Do not resolve labels across function boundary - return None + return None; } } let result = rib.bindings.get(&name).cloned(); if result.is_some() { - return result + return result; } } None @@ -2009,16 +2053,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn check_if_primitive_type_name(&self, name: Name, span: Span) { if let Some(_) = self.primitive_type_table.primitive_types.get(&name) { - span_err!(self.session, span, E0317, - "user-defined types or type parameters cannot shadow the primitive types"); + span_err!(self.session, + span, + E0317, + "user-defined types or type parameters cannot shadow the primitive types"); } } fn resolve_item(&mut self, item: &Item) { let name = item.name; - debug!("(resolving item) resolving {}", - name); + debug!("(resolving item) resolving {}", name); match item.node { ItemEnum(_, ref generics) | @@ -2026,27 +2071,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ItemStruct(_, ref generics) => { self.check_if_primitive_type_name(name, item.span); - self.with_type_parameter_rib(HasTypeParameters(generics, - TypeSpace, - ItemRibKind), + self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind), |this| visit::walk_item(this, item)); } ItemFn(_, _, _, _, ref generics, _) => { - self.with_type_parameter_rib(HasTypeParameters(generics, - FnSpace, - ItemRibKind), + self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind), |this| visit::walk_item(this, item)); } ItemDefaultImpl(_, ref trait_ref) => { self.with_optional_trait_ref(Some(trait_ref), |_, _| {}); } - ItemImpl(_, - _, - ref generics, - ref opt_trait_ref, - ref self_type, - ref impl_items) => { + ItemImpl(_, _, ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => { self.resolve_implementation(generics, opt_trait_ref, &**self_type, @@ -2142,8 +2178,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match self.resolve_crate_relative_path(prefix.span, &prefix.segments, TypeNS) { - Some((def, lp)) => self.record_def(item.id, - PathResolution::new(def, lp, 0)), + Some((def, lp)) => + self.record_def(item.id, PathResolution::new(def, lp, 0)), None => { resolve_error(self, prefix.span, @@ -2163,8 +2199,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where - F: FnOnce(&mut Resolver), + fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) + where F: FnOnce(&mut Resolver) { match type_parameters { HasTypeParameters(generics, space, rib_kind) => { @@ -2177,18 +2213,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if seen_bindings.contains(&name) { resolve_error(self, type_parameter.span, - ResolutionError::NameAlreadyUsedInTypeParameterList( - name) - ); + ResolutionError::NameAlreadyUsedInTypeParameterList(name)); } seen_bindings.insert(name); // plain insert (no renaming) - function_type_rib.bindings.insert(name, - DlDef(DefTyParam(space, - index as u32, - self.ast_map.local_def_id(type_parameter.id), - name))); + function_type_rib.bindings + .insert(name, + DlDef(DefTyParam(space, + index as u32, + self.ast_map + .local_def_id(type_parameter.id), + name))); } self.type_ribs.push(function_type_rib); } @@ -2201,13 +2237,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { f(self); match type_parameters { - HasTypeParameters(..) => { if !self.resolved { self.type_ribs.pop(); } } - NoTypeParameters => { } + HasTypeParameters(..) => { + if !self.resolved { + self.type_ribs.pop(); + } + } + NoTypeParameters => {} } } - fn with_label_rib<F>(&mut self, f: F) where - F: FnOnce(&mut Resolver), + fn with_label_rib<F>(&mut self, f: F) + where F: FnOnce(&mut Resolver) { self.label_ribs.push(Rib::new(NormalRibKind)); f(self); @@ -2216,8 +2256,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn with_constant_rib<F>(&mut self, f: F) where - F: FnOnce(&mut Resolver), + fn with_constant_rib<F>(&mut self, f: F) + where F: FnOnce(&mut Resolver) { self.value_ribs.push(Rib::new(ConstantItemRibKind)); self.type_ribs.push(Rib::new(ConstantItemRibKind)); @@ -2228,10 +2268,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn resolve_function(&mut self, - rib_kind: RibKind, - declaration: &FnDecl, - block: &Block) { + fn resolve_function(&mut self, rib_kind: RibKind, declaration: &FnDecl, block: &Block) { // Create a value rib for the function. self.value_ribs.push(Rib::new(rib_kind)); @@ -2241,9 +2278,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Add each argument to the rib. let mut bindings_list = HashMap::new(); for argument in &declaration.inputs { - self.resolve_pattern(&*argument.pat, - ArgumentIrrefutableMode, - &mut bindings_list); + self.resolve_pattern(&*argument.pat, ArgumentIrrefutableMode, &mut bindings_list); self.visit_ty(&*argument.ty); @@ -2275,22 +2310,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { resolve_error(self, trait_path.span, ResolutionError::IsNotATrait(&*path_names_to_string(trait_path, - path_depth)) - ); + path_depth))); // If it's a typedef, give a note if let DefTy(..) = path_res.base_def { - self.session.span_note(trait_path.span, - "`type` aliases cannot be used for traits"); + self.session + .span_note(trait_path.span, "`type` aliases cannot be used for traits"); } Err(()) } } else { resolve_error(self, trait_path.span, - ResolutionError::UndeclaredTraitName( - &*path_names_to_string(trait_path, path_depth)) - ); + ResolutionError::UndeclaredTraitName(&*path_names_to_string(trait_path, + path_depth))); Err(()) } } @@ -2328,17 +2361,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { result } - fn with_optional_trait_ref<T, F>(&mut self, - opt_trait_ref: Option<&TraitRef>, - f: F) - -> T + fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T where F: FnOnce(&mut Resolver, Option<DefId>) -> T { let mut new_val = None; let mut new_id = None; if let Some(trait_ref) = opt_trait_ref { if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id, - &trait_ref.path, 0) { + &trait_ref.path, + 0) { assert!(path_res.depth == 0); self.record_def(trait_ref.ref_id, path_res); new_val = Some((path_res.base_def.def_id(), trait_ref.clone())); @@ -2435,14 +2466,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } fn check_trait_item<F>(&self, name: Name, span: Span, err: F) - where F: FnOnce(Name, &str) -> ResolutionError { - // If there is a TraitRef in scope for an impl, then the method must be in the trait. + where F: FnOnce(Name, &str) -> ResolutionError + { + // If there is a TraitRef in scope for an impl, then the method must be in the + // trait. if let Some((did, ref trait_ref)) = self.current_trait_ref { if !self.trait_item_map.contains_key(&(name, did)) { let path_str = path_names_to_string(&trait_ref.path, 0); - resolve_error(self, - span, - err(name, &*path_str)); + resolve_error(self, span, err(name, &*path_str)); } } } @@ -2455,9 +2486,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { walk_list!(self, visit_expr, &local.init); // Resolve the pattern. - self.resolve_pattern(&*local.pat, - LocalIrrefutableMode, - &mut HashMap::new()); + self.resolve_pattern(&*local.pat, LocalIrrefutableMode, &mut HashMap::new()); } // build a map from pattern identifiers to binding-info's. @@ -2468,10 +2497,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let mut result = HashMap::new(); pat_bindings_hygienic(&self.def_map, pat, |binding_mode, _id, sp, path1| { let name = mtwt::resolve(path1.node); - result.insert(name, BindingInfo { - span: sp, - binding_mode: binding_mode - }); + result.insert(name, + BindingInfo { + span: sp, + binding_mode: binding_mode, + }); }); return result; } @@ -2480,7 +2510,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // same set of bindings, with the same binding modes for each. fn check_consistent_bindings(&mut self, arm: &Arm) { if arm.pats.is_empty() { - return + return; } let map_0 = self.binding_mode_map(&*arm.pats[0]); for (i, p) in arm.pats.iter().enumerate() { @@ -2488,21 +2518,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { for (&key, &binding_0) in &map_0 { match map_i.get(&key) { - None => { - resolve_error(self, - p.span, - ResolutionError::VariableNotBoundInPattern(key, - i + 1)); - } - Some(binding_i) => { - if binding_0.binding_mode != binding_i.binding_mode { + None => { resolve_error(self, - binding_i.span, - ResolutionError::VariableBoundWithDifferentMode(key, - i + 1) - ); + p.span, + ResolutionError::VariableNotBoundInPattern(key, i + 1)); + } + Some(binding_i) => { + if binding_0.binding_mode != binding_i.binding_mode { + resolve_error(self, + binding_i.span, + ResolutionError::VariableBoundWithDifferentMode(key, + i + 1)); + } } - } } } @@ -2510,8 +2538,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if !map_0.contains_key(&key) { resolve_error(self, binding.span, - ResolutionError::VariableNotBoundInParentPattern(key, - i + 1)); + ResolutionError::VariableNotBoundInParentPattern(key, i + 1)); } } } @@ -2544,10 +2571,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Move down in the graph, if there's an anonymous module rooted here. let orig_module = self.current_module.clone(); match orig_module.anonymous_children.borrow().get(&block.id) { - None => { /* Nothing to do. */ } + None => { + // Nothing to do. + } Some(anonymous_module) => { - debug!("(resolving block) found anonymous module, moving \ - down"); + debug!("(resolving block) found anonymous module, moving down"); self.current_module = anonymous_module.clone(); } } @@ -2559,8 +2587,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let hir::DeclItem(ref i) = declaration.node { match i.node { ItemExternCrate(_) | ItemUse(_) if found_non_item => { - span_err!(self.session, i.span, E0154, - "imports are not allowed after non-item statements"); + span_err!(self.session, + i.span, + E0154, + "imports are not allowed after non-item statements"); } _ => {} } @@ -2586,30 +2616,29 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_type(&mut self, ty: &Ty) { match ty.node { TyPath(ref maybe_qself, ref path) => { - let resolution = - match self.resolve_possibly_assoc_item(ty.id, - maybe_qself.as_ref(), - path, - TypeNS, - true) { - // `<T>::a::b::c` is resolved by typeck alone. - TypecheckRequired => { - // Resolve embedded types. - visit::walk_ty(self, ty); - return; - } - ResolveAttempt(resolution) => resolution, - }; + let resolution = match self.resolve_possibly_assoc_item(ty.id, + maybe_qself.as_ref(), + path, + TypeNS, + true) { + // `<T>::a::b::c` is resolved by typeck alone. + TypecheckRequired => { + // Resolve embedded types. + visit::walk_ty(self, ty); + return; + } + ResolveAttempt(resolution) => resolution, + }; // This is a path in the type namespace. Walk through scopes // looking for it. match resolution { Some(def) => { // Write the result into the def map. - debug!("(resolving type) writing resolution for `{}` \ - (id {}) = {:?}", + debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}", path_names_to_string(path, 0), - ty.id, def); + ty.id, + def); self.record_def(ty.id, def); } None => { @@ -2623,10 +2652,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; let self_type_name = special_idents::type_self.name; - let is_invalid_self_type_name = - path.segments.len() > 0 && - maybe_qself.is_none() && - path.segments[0].identifier.name == self_type_name; + let is_invalid_self_type_name = path.segments.len() > 0 && + maybe_qself.is_none() && + path.segments[0].identifier.name == + self_type_name; if is_invalid_self_type_name { resolve_error(self, ty.span, @@ -2674,19 +2703,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match self.resolve_bare_identifier_pattern(ident.name, pattern.span) { FoundStructOrEnumVariant(def, lp) if const_ok => { - debug!("(resolving pattern) resolving `{}` to \ - struct or enum variant", + debug!("(resolving pattern) resolving `{}` to struct or enum variant", renamed); - self.enforce_default_binding_mode( - pattern, - binding_mode, - "an enum variant"); - self.record_def(pattern.id, PathResolution { - base_def: def, - last_private: lp, - depth: 0 - }); + self.enforce_default_binding_mode(pattern, + binding_mode, + "an enum variant"); + self.record_def(pattern.id, + PathResolution { + base_def: def, + last_private: lp, + depth: 0, + }); } FoundStructOrEnumVariant(..) => { resolve_error( @@ -2697,19 +2725,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ); } FoundConst(def, lp, _) if const_ok => { - debug!("(resolving pattern) resolving `{}` to \ - constant", - renamed); - - self.enforce_default_binding_mode( - pattern, - binding_mode, - "a constant"); - self.record_def(pattern.id, PathResolution { - base_def: def, - last_private: lp, - depth: 0 - }); + debug!("(resolving pattern) resolving `{}` to constant", renamed); + + self.enforce_default_binding_mode(pattern, binding_mode, "a constant"); + self.record_def(pattern.id, + PathResolution { + base_def: def, + last_private: lp, + depth: 0, + }); } FoundConst(def, _, name) => { resolve_error( @@ -2720,8 +2744,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ); } BareIdentifierPatternUnresolved => { - debug!("(resolving pattern) binding `{}`", - renamed); + debug!("(resolving pattern) binding `{}`", renamed); let def_id = self.ast_map.local_def_id(pattern.id); let def = DefLocal(def_id, pattern.id); @@ -2730,11 +2753,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // will be able to distinguish variants from // locals in patterns. - self.record_def(pattern.id, PathResolution { - base_def: def, - last_private: LastMod(AllPublic), - depth: 0 - }); + self.record_def(pattern.id, + PathResolution { + base_def: def, + last_private: LastMod(AllPublic), + depth: 0, + }); // Add the binding to the local ribs, if it // doesn't already exist in the bindings list. (We @@ -2747,7 +2771,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { last_rib.bindings.insert(renamed, DlDef(def)); bindings_list.insert(renamed, pat_id); } else if mode == ArgumentIrrefutableMode && - bindings_list.contains_key(&renamed) { + bindings_list.contains_key(&renamed) { // Forbid duplicate bindings in the same // parameter list. resolve_error( @@ -2756,8 +2780,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ResolutionError::IdentifierBoundMoreThanOnceInParameterList( &ident.name.as_str()) ); - } else if bindings_list.get(&renamed) == - Some(&pat_id) { + } else if bindings_list.get(&renamed) == Some(&pat_id) { // Then this is a duplicate variable in the // same disjunction, which is an error. resolve_error( @@ -2775,21 +2798,24 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { PatEnum(ref path, _) => { // This must be an enum variant, struct or const. - let resolution = - match self.resolve_possibly_assoc_item(pat_id, None, - path, ValueNS, - false) { - // The below shouldn't happen because all - // qualified paths should be in PatQPath. - TypecheckRequired => - self.session.span_bug( - path.span, - "resolve_possibly_assoc_item claimed - that a path in PatEnum requires typecheck - to resolve, but qualified paths should be - PatQPath"), - ResolveAttempt(resolution) => resolution, - }; + let resolution = match self.resolve_possibly_assoc_item(pat_id, + None, + path, + ValueNS, + false) { + // The below shouldn't happen because all + // qualified paths should be in PatQPath. + TypecheckRequired => + self.session.span_bug(path.span, + "resolve_possibly_assoc_item claimed + \ + that a path in PatEnum requires typecheck + \ + to resolve, but qualified paths should be + \ + PatQPath"), + ResolveAttempt(resolution) => resolution, + }; if let Some(path_res) = resolution { match path_res.base_def { DefVariant(..) | DefStruct(..) | DefConst(..) => { @@ -2818,8 +2844,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .as_str()) ); } else { - let const_name = path.segments.last().unwrap() - .identifier.name; + let const_name = path.segments + .last() + .unwrap() + .identifier + .name; let traits = self.get_traits_containing_item(const_name); self.trait_map.insert(pattern.id, traits); self.record_def(pattern.id, path_res); @@ -2839,23 +2868,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { PatQPath(ref qself, ref path) => { // Associated constants only. - let resolution = - match self.resolve_possibly_assoc_item(pat_id, Some(qself), - path, ValueNS, - false) { - TypecheckRequired => { - // All `<T>::CONST` should end up here, and will - // require use of the trait map to resolve - // during typechecking. - let const_name = path.segments.last().unwrap() - .identifier.name; - let traits = self.get_traits_containing_item(const_name); - self.trait_map.insert(pattern.id, traits); - visit::walk_pat(self, pattern); - return true; - } - ResolveAttempt(resolution) => resolution, - }; + let resolution = match self.resolve_possibly_assoc_item(pat_id, + Some(qself), + path, + ValueNS, + false) { + TypecheckRequired => { + // All `<T>::CONST` should end up here, and will + // require use of the trait map to resolve + // during typechecking. + let const_name = path.segments + .last() + .unwrap() + .identifier + .name; + let traits = self.get_traits_containing_item(const_name); + self.trait_map.insert(pattern.id, traits); + visit::walk_pat(self, pattern); + return true; + } + ResolveAttempt(resolution) => resolution, + }; if let Some(path_res) = resolution { match path_res.base_def { // All `<T as Trait>::CONST` should end up here, and @@ -2874,13 +2907,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } } else { - resolve_error( - self, - path.span, - ResolutionError::UnresolvedAssociatedConst( - &path.segments.last().unwrap().identifier.name.as_str() - ) - ); + resolve_error(self, + path.span, + ResolutionError::UnresolvedAssociatedConst(&path.segments + .last() + .unwrap() + .identifier + .name + .as_str())); } visit::walk_pat(self, pattern); } @@ -2891,8 +2925,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.record_def(pattern.id, definition); } result => { - debug!("(resolving pattern) didn't find struct \ - def: {:?}", result); + debug!("(resolving pattern) didn't find struct def: {:?}", result); resolve_error( self, path.span, @@ -2916,21 +2949,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }); } - fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span) + fn resolve_bare_identifier_pattern(&mut self, + name: Name, + span: Span) -> BareIdentifierPatternResolution { let module = self.current_module.clone(); - match self.resolve_item_in_lexical_scope(module, - name, - ValueNS) { + match self.resolve_item_in_lexical_scope(module, name, ValueNS) { Success((target, _)) => { - debug!("(resolve bare identifier pattern) succeeded in \ - finding {} at {:?}", - name, - target.bindings.value_def.borrow()); + debug!("(resolve bare identifier pattern) succeeded in finding {} at {:?}", + name, + target.bindings.value_def.borrow()); match *target.bindings.value_def.borrow() { None => { - panic!("resolved name in the value namespace to a \ - set of name bindings with no def?!"); + panic!("resolved name in the value namespace to a set of name bindings \ + with no def?!"); } Some(def) => { // For the two success cases, this lookup can be @@ -2944,9 +2976,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return FoundConst(def, LastMod(AllPublic), name); } DefStatic(..) => { - resolve_error(self, - span, - ResolutionError::StaticVariableReference); + resolve_error(self, span, ResolutionError::StaticVariableReference); return BareIdentifierPatternUnresolved; } _ => { @@ -2965,11 +2995,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some((span, msg)) => { resolve_error(self, span, ResolutionError::FailedToResolve(&*msg)); } - None => () + None => (), } - debug!("(resolve bare identifier pattern) failed to find {}", - name); + debug!("(resolve bare identifier pattern) failed to find {}", name); return BareIdentifierPatternUnresolved; } } @@ -2982,8 +3011,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { path: &Path, namespace: Namespace, check_ribs: bool) - -> AssocItemResolveResult - { + -> AssocItemResolveResult { let max_assoc_types; match maybe_qself { @@ -3008,8 +3036,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { break; } self.with_no_errors(|this| { - resolution = this.resolve_path(id, path, depth, - TypeNS, true); + resolution = this.resolve_path(id, path, depth, TypeNS, true); }); } if let Some(DefMod(_)) = resolution.map(|r| r.base_def) { @@ -3028,9 +3055,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { path: &Path, path_depth: usize, namespace: Namespace, - check_ribs: bool) -> Option<PathResolution> { + check_ribs: bool) + -> Option<PathResolution> { let span = path.span; - let segments = &path.segments[..path.segments.len()-path_depth]; + let segments = &path.segments[..path.segments.len() - path_depth]; let mk_res = |(def, lp)| PathResolution::new(def, lp, path_depth); @@ -3040,16 +3068,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } // Try to find a path to an item in a module. - let unqualified_def = self.resolve_identifier( - segments.last().unwrap().identifier, - namespace, check_ribs); + let unqualified_def = self.resolve_identifier(segments.last().unwrap().identifier, + namespace, + check_ribs); if segments.len() <= 1 { - return unqualified_def - .and_then(|def| self.adjust_local_def(def, span)) - .map(|def| { - PathResolution::new(def, LastMod(AllPublic), path_depth) - }); + return unqualified_def.and_then(|def| self.adjust_local_def(def, span)) + .map(|def| { + PathResolution::new(def, LastMod(AllPublic), path_depth) + }); } let def = self.resolve_module_relative_path(span, segments, namespace); @@ -3057,7 +3084,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { (Some((ref d, _)), Some(ref ud)) if *d == ud.def => { self.session .add_lint(lint::builtin::UNUSED_QUALIFICATIONS, - id, span, + id, + span, "unnecessary qualification".to_string()); } _ => {} @@ -3082,8 +3110,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } if check_ribs { - if let Some(def) = self.resolve_identifier_in_local_ribs(identifier, - namespace) { + if let Some(def) = self.resolve_identifier_in_local_ribs(identifier, namespace) { return Some(def); } } @@ -3095,15 +3122,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Resolve a local definition, potentially adjusting for closures. fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> { let ribs = match local_def.ribs { - Some((TypeNS, i)) => &self.type_ribs[i+1..], - Some((ValueNS, i)) => &self.value_ribs[i+1..], - _ => &[] as &[_] + Some((TypeNS, i)) => &self.type_ribs[i + 1..], + Some((ValueNS, i)) => &self.value_ribs[i + 1..], + _ => &[] as &[_], }; let mut def = local_def.def; match def { DefUpvar(..) => { - self.session.span_bug(span, - &format!("unexpected {:?} in bindings", def)) + self.session.span_bug(span, &format!("unexpected {:?} in bindings", def)) } DefLocal(_, node_id) => { for rib in ribs { @@ -3115,16 +3141,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let prev_def = def; let node_def_id = self.ast_map.local_def_id(node_id); - let seen = self.freevars_seen.entry(function_id) - .or_insert_with(|| NodeMap()); + let seen = self.freevars_seen + .entry(function_id) + .or_insert_with(|| NodeMap()); if let Some(&index) = seen.get(&node_id) { def = DefUpvar(node_def_id, node_id, index, function_id); continue; } - let vec = self.freevars.entry(function_id) - .or_insert_with(|| vec![]); + let vec = self.freevars + .entry(function_id) + .or_insert_with(|| vec![]); let depth = vec.len(); - vec.push(Freevar { def: prev_def, span: span }); + vec.push(Freevar { + def: prev_def, + span: span, + }); def = DefUpvar(node_def_id, node_id, depth, function_id); seen.insert(node_id, depth); @@ -3133,20 +3164,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // This was an attempt to access an upvar inside a // named function item. This is not allowed, so we // report an error. - resolve_error( - self, - span, - ResolutionError::CannotCaptureDynamicEnvironmentInFnItem - ); + resolve_error(self, + span, + ResolutionError::CannotCaptureDynamicEnvironmentInFnItem); return None; } ConstantItemRibKind => { // Still doesn't deal with upvars - resolve_error( - self, - span, - ResolutionError::AttemptToUseNonConstantValueInConstant - ); + resolve_error(self, + span, + ResolutionError::AttemptToUseNonConstantValueInConstant); return None; } } @@ -3195,7 +3222,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some(def) => { // Found it. Stop the search here. let p = child_name_bindings.defined_in_public_namespace(namespace); - let lp = if p {LastMod(AllPublic)} else { + let lp = if p { + LastMod(AllPublic) + } else { LastMod(DependsOn(def.def_id())) }; return ChildNameDefinition(def, lp); @@ -3220,7 +3249,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match target.target_module.def_id.get() { Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); - }, + } _ => {} } return ImportNameDefinition(def, LastMod(AllPublic)); @@ -3237,12 +3266,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Finally, search through external children. if namespace == TypeNS { - if let Some(module) = containing_module.external_module_children.borrow() - .get(&name).cloned() { + if let Some(module) = containing_module.external_module_children + .borrow() + .get(&name) + .cloned() { if let Some(def_id) = module.def_id.get() { // track used crates self.used_crates.insert(def_id.krate); - let lp = if module.is_public {LastMod(AllPublic)} else { + let lp = if module.is_public { + LastMod(AllPublic) + } else { LastMod(DependsOn(def_id)) }; return ChildNameDefinition(DefMod(def_id), lp); @@ -3259,9 +3292,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { segments: &[hir::PathSegment], namespace: Namespace) -> Option<(Def, LastPrivate)> { - let module_path = segments.split_last().unwrap().1.iter() - .map(|ps| ps.identifier.name) - .collect::<Vec<_>>(); + let module_path = segments.split_last() + .unwrap() + .1 + .iter() + .map(|ps| ps.identifier.name) + .collect::<Vec<_>>(); let containing_module; let last_private; @@ -3315,10 +3351,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { span: Span, segments: &[hir::PathSegment], namespace: Namespace) - -> Option<(Def, LastPrivate)> { - let module_path = segments.split_last().unwrap().1.iter() - .map(|ps| ps.identifier.name) - .collect::<Vec<_>>(); + -> Option<(Def, LastPrivate)> { + let module_path = segments.split_last() + .unwrap() + .1 + .iter() + .map(|ps| ps.identifier.name) + .collect::<Vec<_>>(); let root_module = self.graph_root.get_module(); @@ -3355,9 +3394,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } let name = segments.last().unwrap().identifier.name; - match self.resolve_definition_of_name_in_module(containing_module, - name, - namespace) { + match self.resolve_definition_of_name_in_module(containing_module, name, namespace) { NoNameDefinition => { // We failed to resolve the name. Report an error. return None; @@ -3375,7 +3412,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Check the local set of ribs. let (name, ribs) = match namespace { ValueNS => (mtwt::resolve(ident), &self.value_ribs), - TypeNS => (ident.name, &self.type_ribs) + TypeNS => (ident.name, &self.type_ribs), }; for (i, rib) in ribs.iter().enumerate().rev() { @@ -3383,15 +3420,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match def_like { DlDef(def) => { debug!("(resolving path in local ribs) resolved `{}` to {:?} at {}", - name, def, i); + name, + def, + i); return Some(LocalDef { ribs: Some((namespace, i)), - def: def + def: def, }); } def_like => { debug!("(resolving path in local ribs) resolved `{}` to pseudo-def {:?}", - name, def_like); + name, + def_like); return None; } } @@ -3404,25 +3444,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_item_by_name_in_lexical_scope(&mut self, name: Name, namespace: Namespace) - -> Option<Def> { + -> Option<Def> { // Check the items. let module = self.current_module.clone(); - match self.resolve_item_in_lexical_scope(module, - name, - namespace) { + match self.resolve_item_in_lexical_scope(module, name, namespace) { Success((target, _)) => { match (*target.bindings).def_for_namespace(namespace) { None => { // This can happen if we were looking for a type and // found a module instead. Modules don't have defs. - debug!("(resolving item path by identifier in lexical \ - scope) failed to resolve {} after success...", - name); + debug!("(resolving item path by identifier in lexical scope) failed to \ + resolve {} after success...", + name); None } Some(def) => { - debug!("(resolving item path in lexical scope) \ - resolved `{}` to item", + debug!("(resolving item path in lexical scope) resolved `{}` to item", name); // This lookup is "all public" because it only searched // for one identifier in the current module (couldn't @@ -3435,8 +3472,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { panic!("unexpected indeterminate result"); } Failed(err) => { - debug!("(resolving item path by identifier in lexical scope) \ - failed to resolve {}", name); + debug!("(resolving item path by identifier in lexical scope) failed to resolve {}", + name); if let Some((span, msg)) = err { resolve_error(self, span, ResolutionError::FailedToResolve(&*msg)) @@ -3447,8 +3484,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn with_no_errors<T, F>(&mut self, f: F) -> T where - F: FnOnce(&mut Resolver) -> T, + fn with_no_errors<T, F>(&mut self, f: F) -> T + where F: FnOnce(&mut Resolver) -> T { self.emit_errors = false; let rs = f(self); @@ -3457,8 +3494,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion { - fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks) - -> Option<(Path, NodeId, FallbackChecks)> { + fn extract_path_and_node_id(t: &Ty, + allow: FallbackChecks) + -> Option<(Path, NodeId, FallbackChecks)> { match t.node { TyPath(None, ref path) => Some((path.clone(), t.id, allow)), TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics), @@ -3470,8 +3508,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name]) - -> Option<Rc<Module>> { + fn get_module(this: &mut Resolver, + span: Span, + name_path: &[ast::Name]) + -> Option<Rc<Module>> { let root = this.current_module.clone(); let last_name = name_path.last().unwrap(); @@ -3481,7 +3521,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { None => { match this.current_module.children.borrow().get(last_name) { Some(child) => child.get_module_if_available(), - None => None + None => None, } } } @@ -3492,7 +3532,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { span, PathSearch) { Success((module, _)) => Some(module), - _ => None + _ => None, } } } @@ -3502,13 +3542,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let sig = match this.ast_map.get(node_id) { hir_map::NodeTraitItem(trait_item) => match trait_item.node { hir::MethodTraitItem(ref sig, _) => sig, - _ => return false + _ => return false, }, hir_map::NodeImplItem(impl_item) => match impl_item.node { hir::MethodImplItem(ref sig, _) => sig, - _ => return false + _ => return false, }, - _ => return false + _ => return false, }; sig.explicit_self.node == hir::SelfStatic } else { @@ -3548,7 +3588,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(binding) = module.children.borrow().get(&name) { if let Some(DefMethod(did)) = binding.def_for_namespace(ValueNS) { if is_static_method(self, did) { - return StaticMethod(path_names_to_string(&path, 0)) + return StaticMethod(path_names_to_string(&path, 0)); } if self.current_trait_ref.is_some() { return TraitItem; @@ -3598,9 +3638,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // the typo'd name's length. let max_distance = std::cmp::max(name.len(), 3) / 3; - if !values.is_empty() && - values[smallest] <= max_distance && - name != &maybes[smallest][..] { + if !values.is_empty() && values[smallest] <= max_distance && name != &maybes[smallest][..] { Some(maybes[smallest].to_string()) @@ -3618,22 +3656,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Next, resolve the node. match expr.node { ExprPath(ref maybe_qself, ref path) => { - let resolution = - match self.resolve_possibly_assoc_item(expr.id, - maybe_qself.as_ref(), - path, - ValueNS, - true) { - // `<T>::a::b::c` is resolved by typeck alone. - TypecheckRequired => { - let method_name = path.segments.last().unwrap().identifier.name; - let traits = self.get_traits_containing_item(method_name); - self.trait_map.insert(expr.id, traits); - visit::walk_expr(self, expr); - return; - } - ResolveAttempt(resolution) => resolution, - }; + let resolution = match self.resolve_possibly_assoc_item(expr.id, + maybe_qself.as_ref(), + path, + ValueNS, + true) { + // `<T>::a::b::c` is resolved by typeck alone. + TypecheckRequired => { + let method_name = path.segments.last().unwrap().identifier.name; + let traits = self.get_traits_containing_item(method_name); + self.trait_map.insert(expr.id, traits); + visit::walk_expr(self, expr); + return; + } + ResolveAttempt(resolution) => resolution, + }; // This is a local path in the value namespace. Walk through // scopes looking for it. @@ -3646,8 +3683,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { expr.span, ResolutionError::StructVariantUsedAsFunction(&*path_name)); - let msg = format!("did you mean to write: \ - `{} {{ /* fields */ }}`?", + let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?", path_name); if self.emit_errors { self.session.fileline_help(expr.span, &msg); @@ -3679,24 +3715,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { this.resolve_path(expr.id, path, 0, TypeNS, false) }); match type_res.map(|r| r.base_def) { - Some(DefTy(struct_id, _)) - if self.structs.contains_key(&struct_id) => { - resolve_error( + Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => { + resolve_error( self, expr.span, ResolutionError::StructVariantUsedAsFunction( &*path_name) ); - let msg = format!("did you mean to write: \ - `{} {{ /* fields */ }}`?", - path_name); - if self.emit_errors { - self.session.fileline_help(expr.span, &msg); - } else { - self.session.span_help(expr.span, &msg); - } + let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?", + path_name); + if self.emit_errors { + self.session.fileline_help(expr.span, &msg); + } else { + self.session.span_help(expr.span, &msg); } + } _ => { // Keep reporting some errors even if they're ignored above. self.resolve_path(expr.id, path, 0, ValueNS, true); @@ -3712,11 +3746,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }); if method_scope && special_names::self_.as_str() == &path_name[..] { - resolve_error( - self, - expr.span, - ResolutionError::SelfNotAvailableInStaticMethod - ); + resolve_error(self, + expr.span, + ResolutionError::SelfNotAvailableInStaticMethod); } else { let last_name = path.segments.last().unwrap().identifier.name; let mut msg = match self.find_fallback_in_self_type(last_name) { @@ -3724,16 +3756,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // limit search to 5 to reduce the number // of stupid suggestions self.find_best_match_for_name(&path_name) - .map_or("".to_string(), - |x| format!("`{}`", x)) + .map_or("".to_string(), |x| format!("`{}`", x)) } Field => format!("`self.{}`", path_name), Method | - TraitItem => - format!("to call `self.{}`", path_name), + TraitItem => format!("to call `self.{}`", path_name), TraitMethod(path_str) | StaticMethod(path_str) => - format!("to call `{}::{}`", path_str, path_name) + format!("to call `{}::{}`", path_str, path_name), }; if !msg.is_empty() { @@ -3742,8 +3772,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { resolve_error(self, expr.span, - ResolutionError::UnresolvedName(&*path_name, - &*msg)); + ResolutionError::UnresolvedName(&*path_name, &*msg)); } } } @@ -3796,16 +3825,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } Some(DlDef(def @ DefLabel(_))) => { // Since this def is a label, it is never read. - self.record_def(expr.id, PathResolution { - base_def: def, - last_private: LastMod(AllPublic), - depth: 0 - }) + self.record_def(expr.id, + PathResolution { + base_def: def, + last_private: LastMod(AllPublic), + depth: 0, + }) } Some(_) => { - self.session.span_bug(expr.span, - "label wasn't mapped to a \ - label def!") + self.session.span_bug(expr.span, "label wasn't mapped to a label def!") } } } @@ -3827,8 +3855,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.trait_map.insert(expr.id, traits); } ExprMethodCall(name, _, _) => { - debug!("(recording candidate traits for expr) recording \ - traits for {}", + debug!("(recording candidate traits for expr) recording traits for {}", expr.id); let traits = self.get_traits_containing_item(name.node); self.trait_map.insert(expr.id, traits); @@ -3840,15 +3867,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } fn get_traits_containing_item(&mut self, name: Name) -> Vec<DefId> { - debug!("(getting traits containing item) looking for '{}'", - name); + debug!("(getting traits containing item) looking for '{}'", name); - fn add_trait_info(found_traits: &mut Vec<DefId>, - trait_def_id: DefId, - name: Name) { + fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name) { debug!("(adding trait info) found trait {:?} for method '{}'", - trait_def_id, - name); + trait_def_id, + name); found_traits.push(trait_def_id); } @@ -3872,7 +3896,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { for (_, child_names) in search_module.children.borrow().iter() { let def = match child_names.def_for_namespace(TypeNS) { Some(def) => def, - None => continue + None => continue, }; let trait_def_id = match def { DefTrait(trait_def_id) => trait_def_id, @@ -3919,21 +3943,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) { debug!("(recording def) recording {:?} for {}", resolution, node_id); - assert!(match resolution.last_private {LastImport{..} => false, _ => true}, + assert!(match resolution.last_private { + LastImport{..} => false, + _ => true, + }, "Import should only be used for `use` directives"); if let Some(prev_res) = self.def_map.borrow_mut().insert(node_id, resolution) { let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP); - self.session.span_bug(span, &format!("path resolved multiple times \ - ({:?} before, {:?} now)", - prev_res, resolution)); + self.session.span_bug(span, + &format!("path resolved multiple times ({:?} before, {:?} now)", + prev_res, + resolution)); } } fn enforce_default_binding_mode(&mut self, - pat: &Pat, - pat_binding_mode: BindingMode, - descr: &str) { + pat: &Pat, + pat_binding_mode: BindingMode, + descr: &str) { match pat_binding_mode { BindByValue(_) => {} BindByRef(..) => { @@ -3966,7 +3994,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { for (&name, import_resolution) in import_resolutions.iter() { let value_repr; match import_resolution.target_for_namespace(ValueNS) { - None => { value_repr = "".to_string(); } + None => { + value_repr = "".to_string(); + } Some(_) => { value_repr = " value:?".to_string(); // FIXME #4954 @@ -3975,7 +4005,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let type_repr; match import_resolution.target_for_namespace(TypeNS) { - None => { type_repr = "".to_string(); } + None => { + type_repr = "".to_string(); + } Some(_) => { type_repr = " type:?".to_string(); // FIXME #4954 @@ -3998,12 +4030,12 @@ fn names_to_string(names: &[Name]) -> String { result.push_str("::") } result.push_str(&name.as_str()); - }; + } result } fn path_names_to_string(path: &Path, depth: usize) -> String { - let names: Vec<ast::Name> = path.segments[..path.segments.len()-depth] + let names: Vec<ast::Name> = path.segments[..path.segments.len() - depth] .iter() .map(|seg| seg.identifier.name) .collect(); @@ -4043,13 +4075,13 @@ pub struct CrateMap { pub export_map: ExportMap, pub trait_map: TraitMap, pub external_exports: ExternalExports, - pub glob_map: Option<GlobMap> + pub glob_map: Option<GlobMap>, } #[derive(PartialEq,Copy, Clone)] pub enum MakeGlobMap { Yes, - No + No, } /// Entry point to crate resolution. @@ -4072,10 +4104,10 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session, trait_map: resolver.trait_map, external_exports: resolver.external_exports, glob_map: if resolver.make_glob_map { - Some(resolver.glob_map) - } else { - None - }, + Some(resolver.glob_map) + } else { + None + }, } } diff --git a/src/librustc_resolve/record_exports.rs b/src/librustc_resolve/record_exports.rs index 0eb1e2cc06f..96fad16536c 100644 --- a/src/librustc_resolve/record_exports.rs +++ b/src/librustc_resolve/record_exports.rs @@ -30,8 +30,8 @@ use syntax::ast; use std::ops::{Deref, DerefMut}; use std::rc::Rc; -struct ExportRecorder<'a, 'b:'a, 'tcx:'b> { - resolver: &'a mut Resolver<'b, 'tcx> +struct ExportRecorder<'a, 'b: 'a, 'tcx: 'b> { + resolver: &'a mut Resolver<'b, 'tcx>, } // Deref and DerefMut impls allow treating ExportRecorder as Resolver. @@ -50,28 +50,26 @@ impl<'a, 'b, 'tcx:'b> DerefMut for ExportRecorder<'a, 'b, 'tcx> { } impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> { - fn record_exports_for_module_subtree(&mut self, - module_: Rc<Module>) { + fn record_exports_for_module_subtree(&mut self, module_: Rc<Module>) { // If this isn't a local krate, then bail out. We don't need to record // exports for nonlocal crates. match module_.def_id.get() { Some(def_id) if def_id.is_local() => { // OK. Continue. - debug!("(recording exports for module subtree) recording \ - exports for local module `{}`", + debug!("(recording exports for module subtree) recording exports for local \ + module `{}`", module_to_string(&*module_)); } None => { // Record exports for the root module. - debug!("(recording exports for module subtree) recording \ - exports for root module `{}`", + debug!("(recording exports for module subtree) recording exports for root module \ + `{}`", module_to_string(&*module_)); } Some(_) => { // Bail out. - debug!("(recording exports for module subtree) not recording \ - exports for `{}`", + debug!("(recording exports for module subtree) not recording exports for `{}`", module_to_string(&*module_)); return; } @@ -118,10 +116,11 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> { match namebindings.def_for_namespace(ns) { Some(d) => { debug!("(computing exports) YES: export '{}' => {:?}", - name, d.def_id()); + name, + d.def_id()); exports.push(Export { name: name, - def_id: d.def_id() + def_id: d.def_id(), }); } d_opt => { @@ -130,25 +129,19 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> { } } - fn add_exports_for_module(&mut self, - exports: &mut Vec<Export>, - module_: &Module) { + fn add_exports_for_module(&mut self, exports: &mut Vec<Export>, module_: &Module) { for (name, import_resolution) in module_.import_resolutions.borrow().iter() { if !import_resolution.is_public { - continue + continue; } let xs = [TypeNS, ValueNS]; for &ns in &xs { match import_resolution.target_for_namespace(ns) { Some(target) => { - debug!("(computing exports) maybe export '{}'", - name); - self.add_exports_of_namebindings(exports, - *name, - &*target.bindings, - ns) + debug!("(computing exports) maybe export '{}'", name); + self.add_exports_of_namebindings(exports, *name, &*target.bindings, ns) } - _ => () + _ => (), } } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 99d7685f7c8..9a21ec86685 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -42,14 +42,14 @@ use std::rc::Rc; #[derive(Copy, Clone,Debug)] pub enum ImportDirectiveSubclass { SingleImport(Name /* target */, Name /* source */), - GlobImport + GlobImport, } /// Whether an import can be shadowed by another import. #[derive(Debug,PartialEq,Clone,Copy)] pub enum Shadowable { Always, - Never + Never, } /// One import directive. @@ -64,13 +64,13 @@ pub struct ImportDirective { } impl ImportDirective { - pub fn new(module_path: Vec<Name> , - subclass: ImportDirectiveSubclass, - span: Span, - id: NodeId, - is_public: bool, - shadowable: Shadowable) - -> ImportDirective { + pub fn new(module_path: Vec<Name>, + subclass: ImportDirectiveSubclass, + span: Span, + id: NodeId, + is_public: bool, + shadowable: Shadowable) + -> ImportDirective { ImportDirective { module_path: module_path, subclass: subclass, @@ -92,9 +92,9 @@ pub struct Target { impl Target { pub fn new(target_module: Rc<Module>, - bindings: Rc<NameBindings>, - shadowable: Shadowable) - -> Target { + bindings: Rc<NameBindings>, + shadowable: Shadowable) + -> Target { Target { target_module: target_module, bindings: bindings, @@ -144,17 +144,16 @@ impl ImportResolution { } } - pub fn target_for_namespace(&self, namespace: Namespace) - -> Option<Target> { + pub fn target_for_namespace(&self, namespace: Namespace) -> Option<Target> { match namespace { - TypeNS => self.type_target.clone(), + TypeNS => self.type_target.clone(), ValueNS => self.value_target.clone(), } } pub fn id(&self, namespace: Namespace) -> NodeId { match namespace { - TypeNS => self.type_id, + TypeNS => self.type_id, ValueNS => self.value_id, } } @@ -168,12 +167,9 @@ impl ImportResolution { target.unwrap().shadowable } - pub fn set_target_and_id(&mut self, - namespace: Namespace, - target: Option<Target>, - id: NodeId) { + pub fn set_target_and_id(&mut self, namespace: Namespace, target: Option<Target>, id: NodeId) { match namespace { - TypeNS => { + TypeNS => { self.type_target = target; self.type_id = id; } @@ -191,8 +187,8 @@ struct ImportResolvingError { help: String, } -struct ImportResolver<'a, 'b:'a, 'tcx:'b> { - resolver: &'a mut Resolver<'b, 'tcx> +struct ImportResolver<'a, 'b: 'a, 'tcx: 'b> { + resolver: &'a mut Resolver<'b, 'tcx>, } impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { @@ -211,7 +207,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { let mut prev_unresolved_imports = 0; loop { debug!("(resolving imports) iteration {}, {} imports left", - i, self.resolver.unresolved_imports); + i, + self.resolver.unresolved_imports); let module_root = self.resolver.graph_root.get_module(); let errors = self.resolve_imports_for_module_subtree(module_root.clone()); @@ -246,7 +243,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { /// Attempts to resolve imports for the given module and all of its /// submodules. - fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) + fn resolve_imports_for_module_subtree(&mut self, + module_: Rc<Module>) -> Vec<ImportResolvingError> { let mut errors = Vec::new(); debug!("(resolving imports for module subtree) resolving {}", @@ -279,8 +277,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { let mut errors = Vec::new(); if module.all_imports_resolved() { - debug!("(resolving imports for module) all imports resolved for \ - {}", + debug!("(resolving imports for module) all imports resolved for {}", module_to_string(&*module)); return errors; } @@ -290,22 +287,19 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { let mut indeterminate_imports = Vec::new(); while module.resolved_import_count.get() + indeterminate_imports.len() < import_count { let import_index = module.resolved_import_count.get(); - match self.resolve_import_for_module(module.clone(), - &imports[import_index]) { + match self.resolve_import_for_module(module.clone(), &imports[import_index]) { ResolveResult::Failed(err) => { let import_directive = &imports[import_index]; let (span, help) = match err { Some((span, msg)) => (span, format!(". {}", msg)), - None => (import_directive.span, String::new()) + None => (import_directive.span, String::new()), }; errors.push(ImportResolvingError { - span: span, - path: import_path_to_string( - &import_directive.module_path, - import_directive.subclass - ), - help: help - }); + span: span, + path: import_path_to_string(&import_directive.module_path, + import_directive.subclass), + help: help, + }); } ResolveResult::Indeterminate => {} ResolveResult::Success(()) => { @@ -354,7 +348,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { ResolveResult::Failed(err) => { resolution_result = ResolveResult::Failed(err); None - }, + } ResolveResult::Indeterminate => { resolution_result = ResolveResult::Indeterminate; None @@ -371,20 +365,18 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { match import_directive.subclass { SingleImport(target, source) => { - resolution_result = - self.resolve_single_import(&module_, - containing_module, - target, - source, - import_directive, - lp); + resolution_result = self.resolve_single_import(&module_, + containing_module, + target, + source, + import_directive, + lp); } GlobImport => { - resolution_result = - self.resolve_glob_import(&module_, - containing_module, - import_directive, - lp); + resolution_result = self.resolve_glob_import(&module_, + containing_module, + import_directive, + lp); } } } @@ -433,8 +425,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { directive: &ImportDirective, lp: LastPrivate) -> ResolveResult<()> { - debug!("(resolving single import) resolving `{}` = `{}::{}` from \ - `{}` id {}, last private {:?}", + debug!("(resolving single import) resolving `{}` = `{}::{}` from `{}` id {}, last \ + private {:?}", target, module_to_string(&*target_module), source, @@ -445,9 +437,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { let lp = match lp { LastMod(lp) => lp, LastImport {..} => { - self.resolver.session - .span_bug(directive.span, - "not expecting Import here, must be LastMod") + self.resolver + .session + .span_bug(directive.span, "not expecting Import here, must be LastMod") } }; @@ -472,11 +464,10 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { value_result = BoundResult(target_module.clone(), (*child_name_bindings).clone()); if directive.is_public && !child_name_bindings.is_public(ValueNS) { - let msg = format!("`{}` is private, and cannot be reexported", - source); - let note_msg = - format!("Consider marking `{}` as `pub` in the imported module", - source); + let msg = format!("`{}` is private, and cannot be reexported", source); + let note_msg = format!("Consider marking `{}` as `pub` in the imported \ + module", + source); span_err!(self.resolver.session, directive.span, E0364, "{}", &msg); self.resolver.session.span_note(directive.span, ¬e_msg); pub_err = true; @@ -487,8 +478,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { type_result = BoundResult(target_module.clone(), (*child_name_bindings).clone()); if !pub_err && directive.is_public && !child_name_bindings.is_public(TypeNS) { - let msg = format!("`{}` is private, and cannot be reexported", - source); + let msg = format!("`{}` is private, and cannot be reexported", source); let note_msg = format!("Consider declaring module `{}` as a `pub mod`", source); span_err!(self.resolver.session, directive.span, E0365, "{}", &msg); @@ -510,8 +500,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // able to resolve this import. if target_module.pub_glob_count.get() > 0 { - debug!("(resolving single import) unresolved pub glob; \ - bailing out"); + debug!("(resolving single import) unresolved pub glob; bailing out"); return ResolveResult::Indeterminate; } @@ -531,14 +520,13 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { type_result = UnboundResult; } } - Some(import_resolution) - if import_resolution.outstanding_references == 0 => { + Some(import_resolution) if import_resolution.outstanding_references == 0 => { fn get_binding(this: &mut Resolver, import_resolution: &ImportResolution, namespace: Namespace, source: Name) - -> NamespaceResult { + -> NamespaceResult { // Import resolutions must be declared with "pub" // in order to be exported. @@ -555,8 +543,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { bindings, shadowable: _ }) => { - debug!("(resolving single import) found \ - import in ns {:?}", namespace); + debug!("(resolving single import) found import in ns {:?}", + namespace); let id = import_resolution.id(namespace); // track used imports and extern crates as well this.used_imports.insert((id, namespace)); @@ -564,7 +552,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { match target_module.def_id.get() { Some(DefId{krate: kid, ..}) => { this.used_crates.insert(kid); - }, + } _ => {} } return BoundResult(target_module, bindings); @@ -603,8 +591,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // In this case we continue as if we resolved the import and let the // check_for_conflicts_between_imports_and_items call below handle // the conflict - match (module_.def_id.get(), target_module.def_id.get()) { - (Some(id1), Some(id2)) if id1 == id2 => { + match (module_.def_id.get(), target_module.def_id.get()) { + (Some(id1), Some(id2)) if id1 == id2 => { if value_result.is_unknown() { value_result = UnboundResult; } @@ -612,10 +600,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { type_result = UnboundResult; } } - _ => { + _ => { // The import is unresolved. Bail out. - debug!("(resolving single import) unresolved import; \ - bailing out"); + debug!("(resolving single import) unresolved import; bailing out"); return ResolveResult::Indeterminate; } } @@ -668,17 +655,15 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { debug!("(resolving single import) found {:?} target: {:?}", namespace_name, name_bindings.def_for_namespace(namespace)); - self.check_for_conflicting_import( - &import_resolution, - directive.span, - target, - namespace); - - self.check_that_import_is_importable( - &**name_bindings, - directive.span, - target, - namespace); + self.check_for_conflicting_import(&import_resolution, + directive.span, + target, + namespace); + + self.check_that_import_is_importable(&**name_bindings, + directive.span, + target, + namespace); let target = Some(Target::new(target_module.clone(), name_bindings.clone(), @@ -687,7 +672,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { import_resolution.is_public = directive.is_public; *used_public = name_bindings.defined_in_public_namespace(namespace); } - UnboundResult => { /* Continue. */ } + UnboundResult => { + // Continue. + } UnknownResult => { panic!("{:?} result should be known at this point", namespace_name); } @@ -697,11 +684,10 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { check_and_write_import(TypeNS, &type_result, &mut type_used_public); } - self.check_for_conflicts_between_imports_and_items( - module_, - import_resolution, - directive.span, - target); + self.check_for_conflicts_between_imports_and_items(module_, + import_resolution, + directive.span, + target); if value_result.is_unbound() && type_result.is_unbound() { let msg = format!("There is no `{}` in `{}`", @@ -720,33 +706,45 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // purposes it's good enough to just favor one over the other. let value_def_and_priv = import_resolution.value_target.as_ref().map(|target| { let def = target.bindings.def_for_namespace(ValueNS).unwrap(); - (def, if value_used_public { lp } else { DependsOn(def.def_id()) }) + (def, + if value_used_public { + lp + } else { + DependsOn(def.def_id()) + }) }); let type_def_and_priv = import_resolution.type_target.as_ref().map(|target| { let def = target.bindings.def_for_namespace(TypeNS).unwrap(); - (def, if type_used_public { lp } else { DependsOn(def.def_id()) }) + (def, + if type_used_public { + lp + } else { + DependsOn(def.def_id()) + }) }); let import_lp = LastImport { value_priv: value_def_and_priv.map(|(_, p)| p), value_used: Used, type_priv: type_def_and_priv.map(|(_, p)| p), - type_used: Used + type_used: Used, }; if let Some((def, _)) = value_def_and_priv { - self.resolver.def_map.borrow_mut().insert(directive.id, PathResolution { - base_def: def, - last_private: import_lp, - depth: 0 - }); + self.resolver.def_map.borrow_mut().insert(directive.id, + PathResolution { + base_def: def, + last_private: import_lp, + depth: 0, + }); } if let Some((def, _)) = type_def_and_priv { - self.resolver.def_map.borrow_mut().insert(directive.id, PathResolution { - base_def: def, - last_private: import_lp, - depth: 0 - }); + self.resolver.def_map.borrow_mut().insert(directive.id, + PathResolution { + base_def: def, + last_private: import_lp, + depth: 0, + }); } debug!("(resolving single import) successfully resolved import"); @@ -774,8 +772,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // We must bail out if the node has unresolved imports of any kind // (including globs). if (*target_module).pub_count.get() > 0 { - debug!("(resolving glob import) target module has unresolved \ - pub imports; bailing out"); + debug!("(resolving glob import) target module has unresolved pub imports; bailing out"); return ResolveResult::Indeterminate; } @@ -787,21 +784,18 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // This means we are trying to glob import a module into itself, // and it is a no-go debug!("(resolving glob imports) target module is current module; giving up"); - return ResolveResult::Failed(Some(( - import_directive.span, - "Cannot glob-import a module into itself.".into() - ))); + return ResolveResult::Failed(Some((import_directive.span, + "Cannot glob-import a module into itself.".into()))); } for (name, target_import_resolution) in import_resolutions.iter() { - debug!("(resolving glob import) writing module resolution \ - {} into `{}`", + debug!("(resolving glob import) writing module resolution {} into `{}`", *name, module_to_string(module_)); if !target_import_resolution.is_public { debug!("(resolving glob import) nevermind, just kidding"); - continue + continue; } // Here we merge two import resolutions. @@ -843,10 +837,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // Simple: just copy the old import resolution. let mut new_import_resolution = ImportResolution::new(id, is_public); - new_import_resolution.value_target = - target_import_resolution.value_target.clone(); - new_import_resolution.type_target = - target_import_resolution.type_target.clone(); + new_import_resolution.value_target = target_import_resolution.value_target.clone(); + new_import_resolution.type_target = target_import_resolution.type_target.clone(); import_resolutions.insert(*name, new_import_resolution); } @@ -865,8 +857,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // Add external module children from the containing module. for (&name, module) in target_module.external_module_children.borrow().iter() { - let name_bindings = - Rc::new(Resolver::create_name_bindings_from_module(module.clone())); + let name_bindings = Rc::new(Resolver::create_name_bindings_from_module(module.clone())); self.merge_import_resolution(module_, target_module.clone(), import_directive, @@ -876,11 +867,12 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // Record the destination of this import if let Some(did) = target_module.def_id.get() { - self.resolver.def_map.borrow_mut().insert(id, PathResolution { - base_def: DefMod(did), - last_private: lp, - depth: 0 - }); + self.resolver.def_map.borrow_mut().insert(id, + PathResolution { + base_def: DefMod(did), + last_private: lp, + depth: 0, + }); } debug!("(resolving glob import) successfully resolved import"); @@ -898,10 +890,11 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { let mut import_resolutions = module_.import_resolutions.borrow_mut(); let dest_import_resolution = import_resolutions.entry(name) - .or_insert_with(|| ImportResolution::new(id, is_public)); + .or_insert_with(|| { + ImportResolution::new(id, is_public) + }); - debug!("(resolving glob import) writing resolution `{}` in `{}` \ - to `{}`", + debug!("(resolving glob import) writing resolution `{}` in `{}` to `{}`", name, module_to_string(&*containing_module), module_to_string(module_)); @@ -918,18 +911,20 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { }; debug!("(resolving glob import) ... for {} target", namespace_name); if dest_import_resolution.shadowable(namespace) == Shadowable::Never { - let msg = format!("a {} named `{}` has already been imported \ - in this module", + let msg = format!("a {} named `{}` has already been imported in this \ + module", namespace_name, name); - span_err!(self.resolver.session, import_directive.span, E0251, "{}", msg); + span_err!(self.resolver.session, + import_directive.span, + E0251, + "{}", + msg); } else { let target = Target::new(containing_module.clone(), name_bindings.clone(), import_directive.shadowable); - dest_import_resolution.set_target_and_id(namespace, - Some(target), - id); + dest_import_resolution.set_target_and_id(namespace, Some(target), id); } } }; @@ -939,11 +934,10 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { dest_import_resolution.is_public = is_public; - self.check_for_conflicts_between_imports_and_items( - module_, - dest_import_resolution, - import_directive.span, - name); + self.check_for_conflicts_between_imports_and_items(module_, + dest_import_resolution, + import_directive.span, + name); } /// Checks that imported names and items don't have the same name. @@ -963,28 +957,31 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { TypeNS => { if let Some(ref ty_def) = *target.bindings.type_def.borrow() { match ty_def.module_def { - Some(ref module) - if module.kind.get() == ModuleKind::NormalModuleKind => - "module", - Some(ref module) - if module.kind.get() == ModuleKind::TraitModuleKind => - "trait", + Some(ref module) if module.kind.get() == + ModuleKind::NormalModuleKind => "module", + Some(ref module) if module.kind.get() == + ModuleKind::TraitModuleKind => "trait", _ => "type", } - } else { "type" } - }, + } else { + "type" + } + } ValueNS => "value", }; - span_err!(self.resolver.session, import_span, E0252, - "a {} named `{}` has already been imported \ - in this module", ns_word, - name); + span_err!(self.resolver.session, + import_span, + E0252, + "a {} named `{}` has already been imported in this module", + ns_word, + name); let use_id = import_resolution.id(namespace); let item = self.resolver.ast_map.expect_item(use_id); // item is syntax::ast::Item; - span_note!(self.resolver.session, item.span, - "previous import of `{}` here", - name); + span_note!(self.resolver.session, + item.span, + "previous import of `{}` here", + name); } Some(_) | None => {} } @@ -997,8 +994,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { name: Name, namespace: Namespace) { if !name_bindings.defined_in_namespace_with(namespace, DefModifiers::IMPORTABLE) { - let msg = format!("`{}` is not directly importable", - name); + let msg = format!("`{}` is not directly importable", name); span_err!(self.resolver.session, import_span, E0253, "{}", &msg[..]); } } @@ -1006,8 +1002,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { /// Checks that imported names and items don't have the same name. fn check_for_conflicts_between_imports_and_items(&mut self, module: &Module, - import_resolution: - &ImportResolution, + import_resolution: &ImportResolution, import_span: Span, name: Name) { // First, check for conflicts between imports and `extern crate`s. @@ -1016,8 +1011,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { .contains_key(&name) { match import_resolution.type_target { Some(ref target) if target.shadowable != Shadowable::Always => { - let msg = format!("import `{0}` conflicts with imported \ - crate in this module \ + let msg = format!("import `{0}` conflicts with imported crate in this module \ (maybe you meant `use {0}::*`?)", name); span_err!(self.resolver.session, import_span, E0254, "{}", &msg[..]); @@ -1031,7 +1025,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { let name_bindings = match children.get(&name) { None => { // There can't be any conflicts. - return + return; } Some(ref name_bindings) => (*name_bindings).clone(), }; @@ -1039,7 +1033,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { match import_resolution.value_target { Some(ref target) if target.shadowable != Shadowable::Always => { if let Some(ref value) = *name_bindings.value_def.borrow() { - span_err!(self.resolver.session, import_span, E0255, + span_err!(self.resolver.session, + import_span, + E0255, "import `{}` conflicts with value in this module", name); if let Some(span) = value.value_span { @@ -1054,17 +1050,18 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { Some(ref target) if target.shadowable != Shadowable::Always => { if let Some(ref ty) = *name_bindings.type_def.borrow() { let (what, note) = match ty.module_def { - Some(ref module) - if module.kind.get() == ModuleKind::NormalModuleKind => - ("existing submodule", "note conflicting module here"), - Some(ref module) - if module.kind.get() == ModuleKind::TraitModuleKind => - ("trait in this module", "note conflicting trait here"), - _ => ("type in this module", "note conflicting type here"), + Some(ref module) if module.kind.get() == ModuleKind::NormalModuleKind => + ("existing submodule", "note conflicting module here"), + Some(ref module) if module.kind.get() == ModuleKind::TraitModuleKind => + ("trait in this module", "note conflicting trait here"), + _ => ("type in this module", "note conflicting type here"), }; - span_err!(self.resolver.session, import_span, E0256, + span_err!(self.resolver.session, + import_span, + E0256, "import `{}` conflicts with {}", - name, what); + name, + what); if let Some(span) = ty.type_span { self.resolver.session.span_note(span, note); } @@ -1075,28 +1072,25 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { } } -fn import_path_to_string(names: &[Name], - subclass: ImportDirectiveSubclass) - -> String { +fn import_path_to_string(names: &[Name], subclass: ImportDirectiveSubclass) -> String { if names.is_empty() { import_directive_subclass_to_string(subclass) } else { (format!("{}::{}", names_to_string(names), - import_directive_subclass_to_string(subclass))).to_string() + import_directive_subclass_to_string(subclass))) + .to_string() } } fn import_directive_subclass_to_string(subclass: ImportDirectiveSubclass) -> String { match subclass { SingleImport(_, source) => source.to_string(), - GlobImport => "*".to_string() + GlobImport => "*".to_string(), } } pub fn resolve_imports(resolver: &mut Resolver) { - let mut import_resolver = ImportResolver { - resolver: resolver, - }; + let mut import_resolver = ImportResolver { resolver: resolver }; import_resolver.resolve_imports(); } diff --git a/src/librustc_trans/trans/attributes.rs b/src/librustc_trans/trans/attributes.rs index af4c2205e65..90a649405cd 100644 --- a/src/librustc_trans/trans/attributes.rs +++ b/src/librustc_trans/trans/attributes.rs @@ -142,6 +142,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx }; let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig); + let fn_sig = infer::normalize_associated_type(ccx.tcx(), &fn_sig); let mut attrs = llvm::AttrBuilder::new(); let ret_ty = fn_sig.output; diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 8023f776dde..ecd4c75c9d3 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -38,6 +38,7 @@ use metadata::{csearch, encoder, loader}; use middle::astencode; use middle::cfg; use middle::def_id::DefId; +use middle::infer; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::weak_lang_items; use middle::pat_util::simple_name; @@ -1905,7 +1906,11 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, debug!("trans_fn(param_substs={:?})", param_substs); let _icx = push_ctxt("trans_fn"); let fn_ty = ccx.tcx().node_id_to_type(id); - let output_type = ccx.tcx().erase_late_bound_regions(&fn_ty.fn_ret()); + let fn_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &fn_ty); + let sig = fn_ty.fn_sig(); + let sig = ccx.tcx().erase_late_bound_regions(&sig); + let sig = infer::normalize_associated_type(ccx.tcx(), &sig); + let output_type = sig.output; let abi = fn_ty.fn_abi(); trans_closure(ccx, decl, body, llfndecl, param_substs, id, attrs, output_type, abi, closure::ClosureEnv::NotClosure); @@ -1936,15 +1941,9 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let ccx = bcx.fcx.ccx; - let result_ty = match ctor_ty.sty { - ty::TyBareFn(_, ref bft) => { - bcx.tcx().erase_late_bound_regions(&bft.sig.output()).unwrap() - } - _ => ccx.sess().bug( - &format!("trans_enum_variant_constructor: \ - unexpected ctor return type {}", - ctor_ty)) - }; + let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig()); + let sig = infer::normalize_associated_type(ccx.tcx(), &sig); + let result_ty = sig.output.unwrap(); // Get location to store the result. If the user does not care about // the result, just make a stack slot @@ -2026,15 +2025,10 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx let ctor_ty = ccx.tcx().node_id_to_type(ctor_id); let ctor_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &ctor_ty); - let result_ty = match ctor_ty.sty { - ty::TyBareFn(_, ref bft) => { - ccx.tcx().erase_late_bound_regions(&bft.sig.output()) - } - _ => ccx.sess().bug( - &format!("trans_enum_variant_or_tuple_like_struct: \ - unexpected ctor return type {}", - ctor_ty)) - }; + let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig()); + let sig = infer::normalize_associated_type(ccx.tcx(), &sig); + let arg_tys = sig.inputs; + let result_ty = sig.output; let (arena, fcx): (TypedArena<_>, FunctionContext); arena = TypedArena::new(); @@ -2044,8 +2038,6 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx assert!(!fcx.needs_ret_allocas); - let arg_tys = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_args()); - if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) { let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot"); let repr = adt::represent_type(ccx, result_ty.unwrap()); diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index c8525e33e26..a52c7f94c3a 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -25,7 +25,7 @@ use llvm::{self, ValueRef, get_params}; use metadata::cstore::LOCAL_CRATE; use middle::def; use middle::def_id::DefId; -use middle::infer::normalize_associated_type; +use middle::infer; use middle::subst; use middle::subst::{Substs}; use rustc::front::map as hir_map; @@ -304,6 +304,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( } }; let sig = tcx.erase_late_bound_regions(sig); + let sig = infer::normalize_associated_type(ccx.tcx(), &sig); let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec()); let tuple_fn_ty = tcx.mk_fn(opt_def_id, tcx.mk_bare_fn(ty::BareFnTy { @@ -466,7 +467,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( // Type scheme of the function item (may have type params) let fn_type_scheme = tcx.lookup_item_type(def_id); - let fn_type = normalize_associated_type(tcx, &fn_type_scheme.ty); + let fn_type = infer::normalize_associated_type(tcx, &fn_type_scheme.ty); // Find the actual function pointer. let mut val = { @@ -605,8 +606,9 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let (abi, ret_ty) = match callee.ty.sty { ty::TyBareFn(_, ref f) => { - let output = bcx.tcx().erase_late_bound_regions(&f.sig.output()); - (f.abi, output) + let sig = bcx.tcx().erase_late_bound_regions(&f.sig); + let sig = infer::normalize_associated_type(bcx.tcx(), &sig); + (f.abi, sig.output) } _ => panic!("expected bare rust fn or closure in trans_call_inner") }; @@ -826,7 +828,9 @@ fn trans_args_under_call_abi<'blk, 'tcx>( ignore_self: bool) -> Block<'blk, 'tcx> { - let args = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_args()); + let sig = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_sig()); + let sig = infer::normalize_associated_type(bcx.tcx(), &sig); + let args = sig.inputs; // Translate the `self` argument first. if !ignore_self { @@ -887,7 +891,10 @@ fn trans_overloaded_call_args<'blk, 'tcx>( ignore_self: bool) -> Block<'blk, 'tcx> { // Translate the `self` argument first. - let arg_tys = bcx.tcx().erase_late_bound_regions( &fn_ty.fn_args()); + let sig = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_sig()); + let sig = infer::normalize_associated_type(bcx.tcx(), &sig); + let arg_tys = sig.inputs; + if !ignore_self { let arg_datum = unpack_datum!(bcx, expr::trans(bcx, arg_exprs[0])); bcx = trans_arg_datum(bcx, @@ -933,8 +940,10 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>, debug!("trans_args(abi={})", abi); let _icx = push_ctxt("trans_args"); - let arg_tys = cx.tcx().erase_late_bound_regions(&fn_ty.fn_args()); - let variadic = fn_ty.fn_sig().0.variadic; + let sig = cx.tcx().erase_late_bound_regions(&fn_ty.fn_sig()); + let sig = infer::normalize_associated_type(cx.tcx(), &sig); + let arg_tys = sig.inputs; + let variadic = sig.variadic; let mut bcx = cx; diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index d3509c2f813..04487a6f2d2 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -210,6 +210,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, tcx.with_freevars(id, |fv| fv.iter().cloned().collect()); let sig = tcx.erase_late_bound_regions(&function_type.sig); + let sig = infer::normalize_associated_type(ccx.tcx(), &sig); trans_closure(ccx, decl, @@ -371,6 +372,8 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( let lloncefn = declare::define_internal_rust_fn(ccx, &function_name, llonce_fn_ty); let sig = tcx.erase_late_bound_regions(&llonce_bare_fn_ty.sig); + let sig = infer::normalize_associated_type(ccx.tcx(), &sig); + let (block_arena, fcx): (TypedArena<_>, FunctionContext); block_arena = TypedArena::new(); fcx = new_fn_ctxt(ccx, diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 2e7b1f31ba9..addac528aa2 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -24,6 +24,7 @@ use llvm::{self, ValueRef}; use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType}; use middle::def_id::DefId; +use middle::infer; use middle::pat_util; use middle::subst::{self, Substs}; use rustc::front::map as hir_map; @@ -262,6 +263,7 @@ impl<'tcx> TypeMap<'tcx> { unique_type_id.push_str(" fn("); let sig = cx.tcx().erase_late_bound_regions(sig); + let sig = infer::normalize_associated_type(cx.tcx(), &sig); for ¶meter_type in &sig.inputs { let parameter_type_id = diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs index a08f33c8899..9e53d72cfb8 100644 --- a/src/librustc_trans/trans/debuginfo/mod.rs +++ b/src/librustc_trans/trans/debuginfo/mod.rs @@ -35,6 +35,7 @@ use rustc_front::hir; use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block}; use trans; use trans::{monomorphize, type_of}; +use middle::infer; use middle::ty::{self, Ty}; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet}; @@ -418,19 +419,23 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // Return type -- llvm::DIBuilder wants this at index 0 assert_type_for_node_id(cx, fn_ast_id, error_reporting_span); let fn_type = cx.tcx().node_id_to_type(fn_ast_id); + let fn_type = monomorphize::apply_param_substs(cx.tcx(), param_substs, &fn_type); let (sig, abi) = match fn_type.sty { ty::TyBareFn(_, ref barefnty) => { - (cx.tcx().erase_late_bound_regions(&barefnty.sig), barefnty.abi) + let sig = cx.tcx().erase_late_bound_regions(&barefnty.sig); + let sig = infer::normalize_associated_type(cx.tcx(), &sig); + (sig, barefnty.abi) } ty::TyClosure(def_id, ref substs) => { let closure_type = cx.tcx().closure_type(def_id, substs); - (cx.tcx().erase_late_bound_regions(&closure_type.sig), closure_type.abi) + let sig = cx.tcx().erase_late_bound_regions(&closure_type.sig); + let sig = infer::normalize_associated_type(cx.tcx(), &sig); + (sig, closure_type.abi) } _ => cx.sess().bug("get_function_metdata: Expected a function type!") }; - let sig = monomorphize::apply_param_substs(cx.tcx(), param_substs, &sig); let mut signature = Vec::with_capacity(sig.inputs.len() + 1); diff --git a/src/librustc_trans/trans/debuginfo/type_names.rs b/src/librustc_trans/trans/debuginfo/type_names.rs index 7400ec3cbcd..c6b5ce43683 100644 --- a/src/librustc_trans/trans/debuginfo/type_names.rs +++ b/src/librustc_trans/trans/debuginfo/type_names.rs @@ -14,6 +14,7 @@ use super::namespace::crate_root_namespace; use trans::common::CrateContext; use middle::def_id::DefId; +use middle::infer; use middle::subst::{self, Substs}; use middle::ty::{self, Ty}; @@ -124,6 +125,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push_str("fn("); let sig = cx.tcx().erase_late_bound_regions(sig); + let sig = infer::normalize_associated_type(cx.tcx(), &sig); if !sig.inputs.is_empty() { for ¶meter_type in &sig.inputs { push_debuginfo_type_name(cx, parameter_type, true, output); diff --git a/src/librustc_trans/trans/declare.rs b/src/librustc_trans/trans/declare.rs index ce9f3b4b05d..b9e74beaf55 100644 --- a/src/librustc_trans/trans/declare.rs +++ b/src/librustc_trans/trans/declare.rs @@ -103,9 +103,6 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, fn_type: ty::Ty<'tcx>) -> ValueRef { debug!("declare_rust_fn(name={:?}, fn_type={:?})", name, fn_type); - let fn_type = infer::normalize_associated_type(ccx.tcx(), &fn_type); - debug!("declare_rust_fn (after normalised associated types) fn_type={:?}", - fn_type); let function_type; // placeholder so that the memory ownership works out ok let (sig, abi, env) = match fn_type.sty { @@ -124,14 +121,15 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, _ => ccx.sess().bug("expected closure or fn") }; - let sig = ty::Binder(ccx.tcx().erase_late_bound_regions(sig)); + let sig = ccx.tcx().erase_late_bound_regions(sig); + let sig = infer::normalize_associated_type(ccx.tcx(), &sig); debug!("declare_rust_fn (after region erasure) sig={:?}", sig); let llfty = type_of::type_of_rust_fn(ccx, env, &sig, abi); debug!("declare_rust_fn llfty={}", ccx.tn().type_to_string(llfty)); // it is ok to directly access sig.0.output because we erased all // late-bound-regions above - let llfn = declare_fn(ccx, name, llvm::CCallConv, llfty, sig.0.output); + let llfn = declare_fn(ccx, name, llvm::CCallConv, llfty, sig.output); attributes::from_fn_type(ccx, fn_type).apply_llfn(llfn); llfn } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 773256a17e4..98114da851f 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -15,6 +15,7 @@ use intrinsics::{self, Intrinsic}; use libc; use llvm; use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind}; +use middle::infer; use middle::subst; use middle::subst::FnSpace; use trans::adt; @@ -170,13 +171,10 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let _icx = push_ctxt("trans_intrinsic_call"); - let (arg_tys, ret_ty) = match callee_ty.sty { - ty::TyBareFn(_, ref f) => { - (bcx.tcx().erase_late_bound_regions(&f.sig.inputs()), - bcx.tcx().erase_late_bound_regions(&f.sig.output())) - } - _ => panic!("expected bare_fn in trans_intrinsic_call") - }; + let sig = ccx.tcx().erase_late_bound_regions(callee_ty.fn_sig()); + let sig = infer::normalize_associated_type(ccx.tcx(), &sig); + let arg_tys = sig.inputs; + let ret_ty = sig.output; let foreign_item = tcx.map.expect_foreign_item(node); let name = foreign_item.name.as_str(); @@ -1330,12 +1328,9 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a> let tcx = bcx.tcx(); - let arg_tys = match callee_ty.sty { - ty::TyBareFn(_, ref f) => { - bcx.tcx().erase_late_bound_regions(&f.sig.inputs()) - } - _ => unreachable!() - }; + let sig = tcx.erase_late_bound_regions(callee_ty.fn_sig()); + let sig = infer::normalize_associated_type(tcx, &sig); + let arg_tys = sig.inputs; // every intrinsic takes a SIMD vector as its first argument require_simd!(arg_tys[0], "input"); diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 2b711be5b07..ff94e4feda2 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -12,6 +12,7 @@ use arena::TypedArena; use back::link; use llvm::{ValueRef, get_params}; use middle::def_id::DefId; +use middle::infer; use middle::subst::{Subst, Substs}; use middle::subst::VecPerParamSpace; use middle::subst; @@ -522,6 +523,7 @@ fn trans_object_shim<'a, 'tcx>( let llfn = declare::define_internal_rust_fn(ccx, &function_name, shim_fn_ty); let sig = ccx.tcx().erase_late_bound_regions(&fty.sig); + let sig = infer::normalize_associated_type(ccx.tcx(), &sig); let empty_substs = tcx.mk_substs(Substs::trans_empty()); let (block_arena, fcx): (TypedArena<_>, FunctionContext); diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 1e9183f309b..1e371a16970 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -11,6 +11,7 @@ #![allow(non_camel_case_types)] use middle::def_id::DefId; +use middle::infer; use middle::subst; use trans::adt; use trans::common::*; @@ -89,7 +90,7 @@ pub fn untuple_arguments<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, llenvironment_type: Option<Type>, - sig: &ty::Binder<ty::FnSig<'tcx>>, + sig: &ty::FnSig<'tcx>, abi: abi::Abi) -> Type { @@ -97,16 +98,17 @@ pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, sig, abi); - let sig = cx.tcx().erase_late_bound_regions(sig); assert!(!sig.variadic); // rust fns are never variadic let mut atys: Vec<Type> = Vec::new(); // First, munge the inputs, if this has the `rust-call` ABI. - let inputs = &if abi == abi::RustCall { - untuple_arguments(cx, &sig.inputs) + let inputs_temp; + let inputs = if abi == abi::RustCall { + inputs_temp = untuple_arguments(cx, &sig.inputs); + &inputs_temp } else { - sig.inputs + &sig.inputs }; // Arg 0: Output pointer. @@ -155,7 +157,9 @@ pub fn type_of_fn_from_ty<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fty: Ty<'tcx>) // FIXME(#19925) once fn item types are // zero-sized, we'll need to do something here if f.abi == abi::Rust || f.abi == abi::RustCall { - type_of_rust_fn(cx, None, &f.sig, f.abi) + let sig = cx.tcx().erase_late_bound_regions(&f.sig); + let sig = infer::normalize_associated_type(cx.tcx(), &sig); + type_of_rust_fn(cx, None, &sig, f.abi) } else { foreign::lltype_for_foreign_fn(cx, fty) } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 34378445c60..7de262dfa5b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1624,7 +1624,6 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, .collect(); tcx.mk_tup(flds) } - hir::TyParen(ref typ) => ast_ty_to_ty(this, rscope, &**typ), hir::TyBareFn(ref bf) => { require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span); let bare_fn = ty_of_bare_fn(this, bf.unsafety, bf.abi, &*bf.decl); diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index f597820639c..5c0b35e46b1 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -92,31 +92,39 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // Determine if the field can be used as a function in some way let field_ty = field.ty(cx, substs); - if let Ok(fn_once_trait_did) = cx.lang_items.require(FnOnceTraitLangItem) { - let infcx = fcx.infcx(); - infcx.probe(|_| { - let fn_once_substs = Substs::new_trait(vec![infcx.next_ty_var()], - Vec::new(), - field_ty); - let trait_ref = ty::TraitRef::new(fn_once_trait_did, - cx.mk_substs(fn_once_substs)); - let poly_trait_ref = trait_ref.to_poly_trait_ref(); - let obligation = Obligation::misc(span, - fcx.body_id, - poly_trait_ref.to_predicate()); - let mut selcx = SelectionContext::new(infcx); - - if selcx.evaluate_obligation(&obligation) { - span_stored_function(); + + match field_ty.sty { + // Not all of these (e.g. unsafe fns) implement FnOnce + // so we look for these beforehand + ty::TyClosure(..) | ty::TyBareFn(..) => span_stored_function(), + // If it's not a simple function, look for things which implement FnOnce + _ => { + if let Ok(fn_once_trait_did) = + cx.lang_items.require(FnOnceTraitLangItem) { + let infcx = fcx.infcx(); + infcx.probe(|_| { + let fn_once_substs = Substs::new_trait(vec![ + infcx.next_ty_var()], + Vec::new(), + field_ty); + let trait_ref = ty::TraitRef::new(fn_once_trait_did, + cx.mk_substs(fn_once_substs)); + let poly_trait_ref = trait_ref.to_poly_trait_ref(); + let obligation = Obligation::misc(span, + fcx.body_id, + poly_trait_ref + .to_predicate()); + let mut selcx = SelectionContext::new(infcx); + + if selcx.evaluate_obligation(&obligation) { + span_stored_function(); + } else { + span_did_you_mean(); + } + }); } else { - span_did_you_mean(); + span_did_you_mean() } - }); - } else { - match field_ty.sty { - // fallback to matching a closure or function pointer - ty::TyClosure(..) | ty::TyBareFn(..) => span_stored_function(), - _ => span_did_you_mean(), } } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 30eb468d9f8..185623a4402 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -775,31 +775,33 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { ref impl_items) => { // Create generics from the generics specified in the impl head. debug!("convert: ast_generics={:?}", generics); + let def_id = ccx.tcx.map.local_def_id(it.id); let ty_generics = ty_generics_for_type_or_impl(ccx, generics); - let ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics); + let mut ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics); debug!("convert: impl_bounds={:?}", ty_predicates); let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty); write_ty_to_tcx(tcx, it.id, selfty); - tcx.register_item_type(ccx.tcx.map.local_def_id(it.id), + tcx.register_item_type(def_id, TypeScheme { generics: ty_generics.clone(), ty: selfty }); - tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id), - ty_predicates.clone()); if let &Some(ref ast_trait_ref) = opt_trait_ref { tcx.impl_trait_refs.borrow_mut().insert( - ccx.tcx.map.local_def_id(it.id), + def_id, Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates), &ExplicitRscope, ast_trait_ref, Some(selfty))) ); } else { - tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id), None); + tcx.impl_trait_refs.borrow_mut().insert(def_id, None); } + enforce_impl_params_are_constrained(tcx, generics, &mut ty_predicates, def_id); + tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone()); + // If there is a trait reference, treat the methods as always public. // This is to work around some incorrect behavior in privacy checking: @@ -844,7 +846,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { generics: ty_generics.clone(), ty: ty, }); - convert_associated_const(ccx, ImplContainer(ccx.tcx.map.local_def_id(it.id)), + convert_associated_const(ccx, ImplContainer(def_id), impl_item.name, impl_item.id, impl_item.vis.inherit_from(parent_visibility), ty, true /* has_value */); @@ -861,7 +863,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty); - convert_associated_type(ccx, ImplContainer(ccx.tcx.map.local_def_id(it.id)), + convert_associated_type(ccx, ImplContainer(def_id), impl_item.name, impl_item.id, impl_item.vis, Some(typ)); } @@ -880,7 +882,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { } }); convert_methods(ccx, - ImplContainer(ccx.tcx.map.local_def_id(it.id)), + ImplContainer(def_id), methods, selfty, &ty_generics, @@ -898,10 +900,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { } } - enforce_impl_params_are_constrained(tcx, - generics, - ccx.tcx.map.local_def_id(it.id), - impl_items); + enforce_impl_lifetimes_are_constrained(tcx, generics, def_id, impl_items); }, hir::ItemTrait(_, _, _, ref trait_items) => { let trait_def = trait_def_of_item(ccx, it); @@ -2377,13 +2376,15 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>( /// Checks that all the type parameters on an impl fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, ast_generics: &hir::Generics, - impl_def_id: DefId, - impl_items: &[P<hir::ImplItem>]) + impl_predicates: &mut ty::GenericPredicates<'tcx>, + impl_def_id: DefId) { let impl_scheme = tcx.lookup_item_type(impl_def_id); - let impl_predicates = tcx.lookup_predicates(impl_def_id); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); + assert!(impl_predicates.predicates.is_empty_in(FnSpace)); + assert!(impl_predicates.predicates.is_empty_in(SelfSpace)); + // The trait reference is an input, so find all type parameters // reachable from there, to start (if this is an inherent impl, // then just examine the self type). @@ -2393,10 +2394,10 @@ fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref)); } - ctp::identify_constrained_type_params(tcx, - impl_predicates.predicates.as_slice(), - impl_trait_ref, - &mut input_parameters); + ctp::setup_constraining_predicates(tcx, + impl_predicates.predicates.get_mut_slice(TypeSpace), + impl_trait_ref, + &mut input_parameters); for (index, ty_param) in ast_generics.ty_params.iter().enumerate() { let param_ty = ty::ParamTy { space: TypeSpace, @@ -2406,8 +2407,25 @@ fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string()); } } +} +fn enforce_impl_lifetimes_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, + ast_generics: &hir::Generics, + impl_def_id: DefId, + impl_items: &[P<hir::ImplItem>]) +{ // Every lifetime used in an associated type must be constrained. + let impl_scheme = tcx.lookup_item_type(impl_def_id); + let impl_predicates = tcx.lookup_predicates(impl_def_id); + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); + + let mut input_parameters: HashSet<_> = + ctp::parameters_for_type(impl_scheme.ty).into_iter().collect(); + if let Some(ref trait_ref) = impl_trait_ref { + input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref)); + } + ctp::identify_constrained_type_params(tcx, + &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters); let lifetimes_in_associated_types: HashSet<_> = impl_items.iter() diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index 7844d71462c..39d5872b3dc 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -84,40 +84,92 @@ pub fn identify_constrained_type_params<'tcx>(_tcx: &ty::ctxt<'tcx>, impl_trait_ref: Option<ty::TraitRef<'tcx>>, input_parameters: &mut HashSet<Parameter>) { - loop { - let num_inputs = input_parameters.len(); - - let poly_projection_predicates = // : iterator over PolyProjectionPredicate - predicates.iter() - .filter_map(|predicate| { - match *predicate { - ty::Predicate::Projection(ref data) => Some(data.clone()), - _ => None, - } - }); - - for poly_projection in poly_projection_predicates { - // Note that we can skip binder here because the impl - // trait ref never contains any late-bound regions. - let projection = poly_projection.skip_binder(); - - // Special case: watch out for some kind of sneaky attempt - // to project out an associated type defined by this very - // trait. - let unbound_trait_ref = &projection.projection_ty.trait_ref; - if Some(unbound_trait_ref.clone()) == impl_trait_ref { - continue; - } + let mut predicates = predicates.to_owned(); + setup_constraining_predicates(_tcx, &mut predicates, impl_trait_ref, input_parameters); +} + - let inputs = parameters_for_trait_ref(&projection.projection_ty.trait_ref); - let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(&p)); - if relies_only_on_inputs { +/// Order the predicates in `predicates` such that each parameter is +/// constrained before it is used, if that is possible, and add the +/// paramaters so constrained to `input_parameters`. For example, +/// imagine the following impl: +/// +/// impl<T: Debug, U: Iterator<Item=T>> Trait for U +/// +/// The impl's predicates are collected from left to right. Ignoring +/// the implicit `Sized` bounds, these are +/// * T: Debug +/// * U: Iterator +/// * <U as Iterator>::Item = T -- a desugared ProjectionPredicate +/// +/// When we, for example, try to go over the trait-reference +/// `IntoIter<u32> as Trait`, we substitute the impl parameters with fresh +/// variables and match them with the impl trait-ref, so we know that +/// `$U = IntoIter<u32>`. +/// +/// However, in order to process the `$T: Debug` predicate, we must first +/// know the value of `$T` - which is only given by processing the +/// projection. As we occasionally want to process predicates in a single +/// pass, we want the projection to come first. In fact, as projections +/// can (acyclically) depend on one another - see RFC447 for details - we +/// need to topologically sort them. +pub fn setup_constraining_predicates<'tcx>(_tcx: &ty::ctxt<'tcx>, + predicates: &mut [ty::Predicate<'tcx>], + impl_trait_ref: Option<ty::TraitRef<'tcx>>, + input_parameters: &mut HashSet<Parameter>) +{ + // The canonical way of doing the needed topological sort + // would be a DFS, but getting the graph and its ownership + // right is annoying, so I am using an in-place fixed-point iteration, + // which is `O(nt)` where `t` is the depth of type-parameter constraints, + // remembering that `t` should be less than 7 in practice. + // + // Basically, I iterate over all projections and swap every + // "ready" projection to the start of the list, such that + // all of the projections before `i` are topologically sorted + // and constrain all the parameters in `input_parameters`. + // + // In the example, `input_parameters` starts by containing `U` - which + // is constrained by the trait-ref - and so on the first pass we + // observe that `<U as Iterator>::Item = T` is a "ready" projection that + // constrains `T` and swap it to front. As it is the sole projection, + // no more swaps can take place afterwards, with the result being + // * <U as Iterator>::Item = T + // * T: Debug + // * U: Iterator + let mut i = 0; + let mut changed = true; + while changed { + changed = false; + + for j in i..predicates.len() { + + if let ty::Predicate::Projection(ref poly_projection) = predicates[j] { + // Note that we can skip binder here because the impl + // trait ref never contains any late-bound regions. + let projection = poly_projection.skip_binder(); + + // Special case: watch out for some kind of sneaky attempt + // to project out an associated type defined by this very + // trait. + let unbound_trait_ref = &projection.projection_ty.trait_ref; + if Some(unbound_trait_ref.clone()) == impl_trait_ref { + continue; + } + + let inputs = parameters_for_trait_ref(&projection.projection_ty.trait_ref); + let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(&p)); + if !relies_only_on_inputs { + continue; + } input_parameters.extend(parameters_for_type(projection.ty)); + } else { + continue; } - } - - if input_parameters.len() == num_inputs { - break; + // fancy control flow to bypass borrow checker + predicates.swap(i, j); + i += 1; + changed = true; } } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 34ddd5726d3..dbf71e431d4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1606,7 +1606,6 @@ impl Clean<Type> for hir::Ty { } } TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)), - TyParen(ref ty) => ty.clean(cx), TyPolyTraitRef(ref bounds) => { PolyTraitRef(bounds.clean(cx)) }, diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 965226f6355..b8482b3a2dc 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1108,8 +1108,9 @@ impl<K, V, S> HashMap<K, V, S> /// /// If the map did not have this key present, `None` is returned. /// - /// If the map did have this key present, that value is returned, and the - /// entry is not updated. See the [module-level documentation] for more. + /// If the map did have this key present, the key is not updated, the + /// value is updated and the old value is returned. + /// See the [module-level documentation] for more. /// /// [module-level documentation]: index.html#insert-and-complex-keys /// diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index d4cef2ab07a..bb7a96bfb4b 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -544,10 +544,7 @@ impl<T, S> HashSet<T, S> /// /// If the set did not have a value present, `true` is returned. /// - /// If the set did have this key present, that value is returned, and the - /// entry is not updated. See the [module-level documentation] for more. - /// - /// [module-level documentation]: index.html#insert-and-complex-keys + /// If the set did have this key present, `false` is returned. /// /// # Examples /// diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index c0cd6d127d2..48631bfc5f9 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -66,7 +66,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult}; /// for _ in 0..10 { /// let (data, tx) = (data.clone(), tx.clone()); /// thread::spawn(move || { -/// // The shared static can only be accessed once the lock is held. +/// // The shared state can only be accessed once the lock is held. /// // Our non-atomic increment is safe because we're the only thread /// // which can access the shared state when the lock is held. /// // diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 3c53db53f85..5bc5567df2f 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -386,24 +386,33 @@ pub fn env() -> Env { let _g = ENV_LOCK.lock(); return unsafe { let mut environ = *environ(); - if environ as usize == 0 { + if environ == ptr::null() { panic!("os::env() failure getting env string from OS: {}", io::Error::last_os_error()); } let mut result = Vec::new(); while *environ != ptr::null() { - result.push(parse(CStr::from_ptr(*environ).to_bytes())); + if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { + result.push(key_value); + } environ = environ.offset(1); } Env { iter: result.into_iter(), _dont_send_or_sync_me: ptr::null_mut() } }; - fn parse(input: &[u8]) -> (OsString, OsString) { - let mut it = input.splitn(2, |b| *b == b'='); - let key = it.next().unwrap().to_vec(); - let default: &[u8] = &[]; - let val = it.next().unwrap_or(default).to_vec(); - (OsStringExt::from_vec(key), OsStringExt::from_vec(val)) + fn parse(input: &[u8]) -> Option<(OsString, OsString)> { + // Strategy (copied from glibc): Variable name and value are separated + // by an ASCII equals sign '='. Since a variable name must not be + // empty, allow variable names starting with an equals sign. Skip all + // malformed lines. + if input.is_empty() { + return None; + } + let pos = input[1..].iter().position(|&b| b == b'=').map(|p| p + 1); + pos.map(|p| ( + OsStringExt::from_vec(input[..p].to_vec()), + OsStringExt::from_vec(input[p+1..].to_vec()), + )) } } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index a34998196e5..43647ea4a2e 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -10,10 +10,10 @@ use ast::{self, TokenTree}; use codemap::{Span, DUMMY_SP}; -use ext::base::{ExtCtxt, MacResult, SyntaxExtension}; +use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension}; use ext::base::{NormalTT, TTMacroExpander}; use ext::tt::macro_parser::{Success, Error, Failure}; -use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal}; +use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal}; use ext::tt::macro_parser::parse; use parse::lexer::new_tt_reader; use parse::parser::Parser; @@ -129,16 +129,20 @@ impl<'a> MacResult for ParserAnyMacro<'a> { struct MacroRulesMacroExpander { name: ast::Ident, imported_from: Option<ast::Ident>, - lhses: Vec<Rc<NamedMatch>>, - rhses: Vec<Rc<NamedMatch>>, + lhses: Vec<TokenTree>, + rhses: Vec<TokenTree>, + valid: bool, } impl TTMacroExpander for MacroRulesMacroExpander { fn expand<'cx>(&self, cx: &'cx mut ExtCtxt, sp: Span, - arg: &[ast::TokenTree]) + arg: &[TokenTree]) -> Box<MacResult+'cx> { + if !self.valid { + return DummyResult::any(sp); + } generic_extension(cx, sp, self.name, @@ -154,9 +158,9 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, sp: Span, name: ast::Ident, imported_from: Option<ast::Ident>, - arg: &[ast::TokenTree], - lhses: &[Rc<NamedMatch>], - rhses: &[Rc<NamedMatch>]) + arg: &[TokenTree], + lhses: &[TokenTree], + rhses: &[TokenTree]) -> Box<MacResult+'cx> { if cx.trace_macros() { println!("{}! {{ {} }}", @@ -169,25 +173,17 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, let mut best_fail_msg = "internal error: ran no matchers".to_string(); for (i, lhs) in lhses.iter().enumerate() { // try each arm's matchers - match **lhs { - MatchedNonterminal(NtTT(ref lhs_tt)) => { - let lhs_tt = match **lhs_tt { - TokenTree::Delimited(_, ref delim) => &delim.tts[..], - _ => panic!(cx.span_fatal(sp, "malformed macro lhs")) - }; - - match TokenTree::parse(cx, lhs_tt, arg) { - Success(named_matches) => { - let rhs = match *rhses[i] { - // okay, what's your transcriber? - MatchedNonterminal(NtTT(ref tt)) => { - match **tt { - // ignore delimiters - TokenTree::Delimited(_, ref delimed) => delimed.tts.clone(), - _ => panic!(cx.span_fatal(sp, "macro rhs must be delimited")), - } - }, - _ => cx.span_bug(sp, "bad thing in rhs") + let lhs_tt = match *lhs { + TokenTree::Delimited(_, ref delim) => &delim.tts[..], + _ => cx.span_bug(sp, "malformed macro lhs") + }; + + match TokenTree::parse(cx, lhs_tt, arg) { + Success(named_matches) => { + let rhs = match rhses[i] { + // ignore delimiters + TokenTree::Delimited(_, ref delimed) => delimed.tts.clone(), + _ => cx.span_bug(sp, "malformed macro rhs"), }; // rhs has holes ( `$id` and `$(...)` that need filled) let trncbr = new_tt_reader(&cx.parse_sess().span_diagnostic, @@ -207,17 +203,14 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, site_span: sp, macro_ident: name }) - } - Failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo { + } + Failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo { best_fail_spot = sp; best_fail_msg = (*msg).clone(); - }, - Error(err_sp, ref msg) => { + }, + Error(err_sp, ref msg) => { panic!(cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..])) - } } - } - _ => cx.bug("non-matcher found in parsed lhses") } } @@ -282,9 +275,16 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt, } }; + let mut valid = true; + // Extract the arguments: let lhses = match **argument_map.get(&lhs_nm.name).unwrap() { - MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(), + MatchedSeq(ref s, _) => { + s.iter().map(|m| match **m { + MatchedNonterminal(NtTT(ref tt)) => (**tt).clone(), + _ => cx.span_bug(def.span, "wrong-structured lhs") + }).collect() + } _ => cx.span_bug(def.span, "wrong-structured lhs") }; @@ -293,41 +293,55 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt, } let rhses = match **argument_map.get(&rhs_nm.name).unwrap() { - MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(), + MatchedSeq(ref s, _) => { + s.iter().map(|m| match **m { + MatchedNonterminal(NtTT(ref tt)) => (**tt).clone(), + _ => cx.span_bug(def.span, "wrong-structured rhs") + }).collect() + } _ => cx.span_bug(def.span, "wrong-structured rhs") }; + for rhs in &rhses { + valid &= check_rhs(cx, rhs); + } + let exp: Box<_> = Box::new(MacroRulesMacroExpander { name: def.ident, imported_from: def.imported_from, lhses: lhses, rhses: rhses, + valid: valid, }); NormalTT(exp, Some(def.span), def.allow_internal_unstable) } -fn check_lhs_nt_follows(cx: &mut ExtCtxt, lhs: &NamedMatch, sp: Span) { - // lhs is going to be like MatchedNonterminal(NtTT(TokenTree::Delimited(...))), where the +fn check_lhs_nt_follows(cx: &mut ExtCtxt, lhs: &TokenTree, sp: Span) { + // lhs is going to be like TokenTree::Delimited(...), where the // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens. match lhs { - &MatchedNonterminal(NtTT(ref inner)) => match &**inner { - &TokenTree::Delimited(_, ref tts) => { - check_matcher(cx, tts.tts.iter(), &Eof); - }, - tt @ &TokenTree::Sequence(..) => { - check_matcher(cx, Some(tt).into_iter(), &Eof); - }, - _ => cx.span_err(sp, "Invalid macro matcher; matchers must be contained \ - in balanced delimiters or a repetition indicator") + &TokenTree::Delimited(_, ref tts) => { + check_matcher(cx, tts.tts.iter(), &Eof); }, - _ => cx.span_bug(sp, "wrong-structured lhs for follow check (didn't find a \ - MatchedNonterminal)") + tt @ &TokenTree::Sequence(..) => { + check_matcher(cx, Some(tt).into_iter(), &Eof); + }, + _ => cx.span_err(sp, "Invalid macro matcher; matchers must be contained \ + in balanced delimiters or a repetition indicator") }; // we don't abort on errors on rejection, the driver will do that for us // after parsing/expansion. we can report every error in every macro this way. } +fn check_rhs(cx: &mut ExtCtxt, rhs: &TokenTree) -> bool { + match *rhs { + TokenTree::Delimited(..) => return true, + _ => cx.span_err(rhs.get_span(), "macro rhs must be delimited") + } + false +} + // returns the last token that was checked, for TokenTree::Sequence. this gets used later on. fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token) -> Option<(Span, Token)> where I: Iterator<Item=&'a TokenTree> { diff --git a/src/test/auxiliary/issue-28927-1.rs b/src/test/auxiliary/issue-28927-1.rs new file mode 100644 index 00000000000..7d6b448df43 --- /dev/null +++ b/src/test/auxiliary/issue-28927-1.rs @@ -0,0 +1,12 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate issue_28927_2 as inner2; +pub use inner2 as bar; diff --git a/src/test/auxiliary/issue-28927-2.rs b/src/test/auxiliary/issue-28927-2.rs new file mode 100644 index 00000000000..c5117005049 --- /dev/null +++ b/src/test/auxiliary/issue-28927-2.rs @@ -0,0 +1,11 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub struct Baz; diff --git a/src/test/compile-fail/cast-rfc0401.rs b/src/test/compile-fail/cast-rfc0401.rs index 4603ed00347..d14b0fa9e66 100644 --- a/src/test/compile-fail/cast-rfc0401.rs +++ b/src/test/compile-fail/cast-rfc0401.rs @@ -37,6 +37,7 @@ fn main() let f: f32 = 1.2; let v = 0 as *const u8; let fat_v : *const [u8] = unsafe { &*(0 as *const [u8; 1])}; + let fat_sv : *const [i8] = unsafe { &*(0 as *const [i8; 1])}; let foo: &Foo = &f; let _ = v as &u8; //~ ERROR non-scalar @@ -94,7 +95,7 @@ fn main() let _ = main as *mut str; //~ ERROR casting let _ = &f as *mut f32; //~ ERROR casting let _ = &f as *const f64; //~ ERROR casting - let _ = fat_v as usize; + let _ = fat_sv as usize; //~^ ERROR casting //~^^ HELP through a thin pointer first @@ -106,7 +107,7 @@ fn main() let _ = main.f as *const u32; //~ ERROR attempted access of field let cf: *const Foo = &0; - let _ = cf as *const [u8]; + let _ = cf as *const [u16]; //~^ ERROR casting //~^^ NOTE vtable kinds let _ = cf as *const Bar; diff --git a/src/test/compile-fail/infinite-instantiation.rs b/src/test/compile-fail/infinite-instantiation.rs index 9b02bf4cb85..28806b6e2ab 100644 --- a/src/test/compile-fail/infinite-instantiation.rs +++ b/src/test/compile-fail/infinite-instantiation.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//~^^^^^^^^^^ ERROR overflow // // We get an error message at the top of file (dummy span). // This is not helpful, but also kind of annoying to prevent, @@ -32,6 +31,7 @@ impl<T:Clone> ToOpt for Option<T> { } fn function<T:ToOpt + Clone>(counter: usize, t: T) { +//~^ ERROR reached the recursion limit during monomorphization if counter > 0 { function(counter - 1, t.to_option()); // FIXME(#4287) Error message should be here. It should be diff --git a/src/test/compile-fail/issue-2392.rs b/src/test/compile-fail/issue-2392.rs index c5598e8785c..47d50eb9d53 100644 --- a/src/test/compile-fail/issue-2392.rs +++ b/src/test/compile-fail/issue-2392.rs @@ -11,6 +11,16 @@ #![feature(core)] use std::boxed::FnBox; +struct FuncContainer { + f1: fn(data: u8), + f2: extern "C" fn(data: u8), + f3: unsafe fn(data: u8), +} + +struct FuncContainerOuter { + container: Box<FuncContainer> +} + struct Obj<F> where F: FnOnce() -> u32 { closure: F, not_closure: usize, @@ -66,3 +76,16 @@ fn main() { check_expression().closure();//~ ERROR no method named `closure` found //~^ NOTE use `(check_expression().closure)(...)` if you meant to call the function stored } + +impl FuncContainerOuter { + fn run(&self) { + unsafe { + (*self.container).f1(1); //~ ERROR no method named `f1` found + //~^ NOTE use `(*self.container.f1)(...)` + (*self.container).f2(1); //~ ERROR no method named `f2` found + //~^ NOTE use `(*self.container.f2)(...)` + (*self.container).f3(1); //~ ERROR no method named `f3` found + //~^ NOTE use `(*self.container.f3)(...)` + } + } +} diff --git a/src/test/compile-fail/issue-29147.rs b/src/test/compile-fail/issue-29147.rs new file mode 100644 index 00000000000..64bfa232f3f --- /dev/null +++ b/src/test/compile-fail/issue-29147.rs @@ -0,0 +1,32 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![recursion_limit="1024"] + +pub struct S0<T>(T,T); +pub struct S1<T>(Option<Box<S0<S0<T>>>>,Option<Box<S0<S0<T>>>>); +pub struct S2<T>(Option<Box<S1<S1<T>>>>,Option<Box<S1<S1<T>>>>); +pub struct S3<T>(Option<Box<S2<S2<T>>>>,Option<Box<S2<S2<T>>>>); +pub struct S4<T>(Option<Box<S3<S3<T>>>>,Option<Box<S3<S3<T>>>>); +pub struct S5<T>(Option<Box<S4<S4<T>>>>,Option<Box<S4<S4<T>>>>,Option<T>); + +trait Foo { fn xxx(&self); } +trait Bar {} // anything local or #[fundamental] + +impl<T> Foo for T where T: Bar, T: Sync { + fn xxx(&self) {} +} + +impl Foo for S5<u32> { fn xxx(&self) {} } +impl Foo for S5<u64> { fn xxx(&self) {} } + +fn main() { + let _ = <S5<_>>::xxx; //~ ERROR cannot resolve `S5<_> : Foo` +} diff --git a/src/test/compile-fail/macro-error.rs b/src/test/compile-fail/macro-error.rs new file mode 100644 index 00000000000..817b675aedf --- /dev/null +++ b/src/test/compile-fail/macro-error.rs @@ -0,0 +1,19 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Check that we report errors at macro definition, not expansion. + +macro_rules! foo { + ($a:expr) => $a; //~ ERROR macro rhs must be delimited +} + +fn main() { + foo!(0); +} diff --git a/src/test/compile-fail/recursion.rs b/src/test/compile-fail/recursion.rs index 55f3b995336..b1d45a82276 100644 --- a/src/test/compile-fail/recursion.rs +++ b/src/test/compile-fail/recursion.rs @@ -8,12 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//~^^^^^^^^^^ ERROR overflow -// -// We get an error message at the top of file (dummy span). -// This is not helpful, but also kind of annoying to prevent, -// so for now just live with it. - enum Nil {NilValue} struct Cons<T> {head:isize, tail:T} trait Dot {fn dot(&self, other:Self) -> isize;} @@ -26,7 +20,7 @@ impl<T:Dot> Dot for Cons<T> { } } fn test<T:Dot> (n:isize, i:isize, first:T, second:T) ->isize { - match n { 0 => {first.dot(second)} + match n { 0 => {first.dot(second)} //~ ERROR overflow // FIXME(#4287) Error message should be here. It should be // a type error to instantiate `test` at a type other than T. _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})} diff --git a/src/test/compile-fail/type-macros-fail.rs b/src/test/compile-fail/type-macros-fail.rs index d51176a925d..756f5d4547a 100644 --- a/src/test/compile-fail/type-macros-fail.rs +++ b/src/test/compile-fail/type-macros-fail.rs @@ -9,7 +9,7 @@ // except according to those terms. macro_rules! Id { - { $T:tt } => $T + ($T:tt) => ($T); } struct Foo<T> { diff --git a/src/test/run-pass/coherence-rfc447-constrained.rs b/src/test/run-pass/coherence-rfc447-constrained.rs new file mode 100644 index 00000000000..4b52378e508 --- /dev/null +++ b/src/test/run-pass/coherence-rfc447-constrained.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// check that trait matching can handle impls whose types are only +// constrained by a projection. + +trait IsU32 {} +impl IsU32 for u32 {} + +trait Mirror { type Image: ?Sized; } +impl<T: ?Sized> Mirror for T { type Image = T; } + +trait Bar {} +impl<U: Mirror, V: Mirror<Image=L>, L: Mirror<Image=U>> Bar for V + where U::Image: IsU32 {} + +trait Foo { fn name() -> &'static str; } +impl Foo for u64 { fn name() -> &'static str { "u64" } } +impl<T: Bar> Foo for T { fn name() -> &'static str { "Bar" }} + +fn main() { + assert_eq!(<u64 as Foo>::name(), "u64"); + assert_eq!(<u32 as Foo>::name(), "Bar"); +} diff --git a/src/test/run-pass/env-funky-keys.rs b/src/test/run-pass/env-funky-keys.rs new file mode 100644 index 00000000000..3ee20980747 --- /dev/null +++ b/src/test/run-pass/env-funky-keys.rs @@ -0,0 +1,45 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ignore this test on Android, because it segfaults there. + +// ignore-android +// ignore-windows +// no-prefer-dynamic + +#![feature(convert)] +#![feature(libc)] + +extern crate libc; + +use libc::c_char; +use libc::execve; +use std::env; +use std::ffi::OsStr; +use std::ptr; + +fn main() { + if env::args_os().next().is_none() { + for (key, value) in env::vars_os() { + panic!("found env value {:?} {:?}", key, value); + } + return; + } + + let current_exe = env::current_exe().unwrap().into_os_string().to_cstring().unwrap(); + let new_env_var = OsStr::new("FOOBAR").to_cstring().unwrap(); + let filename: *const c_char = current_exe.as_ptr(); + let argv: &[*const c_char] = &[ptr::null()]; + let envp: &[*const c_char] = &[new_env_var.as_ptr(), ptr::null()]; + unsafe { + execve(filename, &argv[0], &envp[0]); + } + panic!("execve failed"); +} diff --git a/src/test/run-pass/env-vars.rs b/src/test/run-pass/env-vars.rs index d86f63c9cb9..933d9a728db 100644 --- a/src/test/run-pass/env-vars.rs +++ b/src/test/run-pass/env-vars.rs @@ -14,10 +14,7 @@ use std::env::*; fn main() { for (k, v) in vars_os() { let v2 = var_os(&k); - // MingW seems to set some funky environment variables like - // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned - // from vars() but not visible from var(). - assert!(v2.is_none() || v2.as_ref().map(|s| &**s) == Some(&*v), + assert!(v2.as_ref().map(|s| &**s) == Some(&*v), "bad vars->var transition: {:?} {:?} {:?}", k, v, v2); } } diff --git a/src/test/run-pass/issue-23406.rs b/src/test/run-pass/issue-23406.rs new file mode 100644 index 00000000000..c3c1b755af8 --- /dev/null +++ b/src/test/run-pass/issue-23406.rs @@ -0,0 +1,23 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Inner { + type T; +} + +impl<'a> Inner for &'a i32 { + type T = i32; +} + +fn f<'a>(x: &'a i32) -> <&'a i32 as Inner>::T { + *x +} + +fn main() {} diff --git a/src/test/run-pass/issue-23598.rs b/src/test/run-pass/issue-23598.rs new file mode 100644 index 00000000000..5f1c79a3c15 --- /dev/null +++ b/src/test/run-pass/issue-23598.rs @@ -0,0 +1,22 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Collection where for<'a> &'a Self: IntoIterator { + fn my_iter(&self) -> <&Self as IntoIterator>::IntoIter { + self.into_iter() + } +} + +impl<T> Collection for [T] { } + +fn main() { + let v = [0usize]; + let _ = v.my_iter(); +} diff --git a/src/test/run-pass/issue-29147.rs b/src/test/run-pass/issue-29147.rs new file mode 100644 index 00000000000..026b98905d0 --- /dev/null +++ b/src/test/run-pass/issue-29147.rs @@ -0,0 +1,36 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![recursion_limit="1024"] + +use std::mem; + +pub struct S0<T>(T,T); +pub struct S1<T>(Option<Box<S0<S0<T>>>>,Option<Box<S0<S0<T>>>>); +pub struct S2<T>(Option<Box<S1<S1<T>>>>,Option<Box<S1<S1<T>>>>); +pub struct S3<T>(Option<Box<S2<S2<T>>>>,Option<Box<S2<S2<T>>>>); +pub struct S4<T>(Option<Box<S3<S3<T>>>>,Option<Box<S3<S3<T>>>>); +pub struct S5<T>(Option<Box<S4<S4<T>>>>,Option<Box<S4<S4<T>>>>,Option<T>); + +trait Foo { fn xxx(&self); } +/// some local of #[fundamental] trait +trait Bar {} + +impl<T> Foo for T where T: Bar, T: Sync { + fn xxx(&self) {} +} + +impl Foo for S5<u8> { fn xxx(&self) {} } + +fn main() { + let s = S5(None,None,None); + s.xxx(); + assert_eq!(mem::size_of_val(&s.2), mem::size_of::<Option<u8>>()); +} diff --git a/src/test/run-pass/trait-copy-guessing.rs b/src/test/run-pass/trait-copy-guessing.rs new file mode 100644 index 00000000000..71cd3c9441e --- /dev/null +++ b/src/test/run-pass/trait-copy-guessing.rs @@ -0,0 +1,46 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// "guessing" in trait selection can affect `copy_or_move`. Check that this +// is correctly handled. I am not sure what is the "correct" behaviour, +// but we should at least not ICE. + +use std::mem; + +struct U([u8; 1337]); + +struct S<'a,T:'a>(&'a T); +impl<'a, T> Clone for S<'a, T> { fn clone(&self) -> Self { S(self.0) } } +/// This impl triggers inference "guessing" - S<_>: Copy => _ = U +impl<'a> Copy for S<'a, Option<U>> {} + +fn assert_impls_fn<R,T: Fn()->R>(_: &T){} + +fn main() { + let n = None; + let e = S(&n); + let f = || { + // S being copy is critical for this to work + drop(e); + mem::size_of_val(e.0) + }; + assert_impls_fn(&f); + assert_eq!(f(), 1337+1); + + assert_eq!((|| { + // S being Copy is not critical here, but + // we check it anyway. + let n = None; + let e = S(&n); + let ret = mem::size_of_val(e.0); + drop(e); + ret + })(), 1337+1); +} diff --git a/src/test/rustdoc/issue-28927.rs b/src/test/rustdoc/issue-28927.rs new file mode 100644 index 00000000000..b3096a94962 --- /dev/null +++ b/src/test/rustdoc/issue-28927.rs @@ -0,0 +1,16 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:issue-28927-2.rs +// aux-build:issue-28927-1.rs +// ignore-cross-compile + +extern crate issue_28927_1 as inner1; +pub use inner1 as foo; |
